POJ 1077 Eight
生活随笔
收集整理的這篇文章主要介紹了
POJ 1077 Eight
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
題意:經(jīng)典的八數(shù)碼=3=
3*3的格子,里面有1~8這8個(gè)數(shù)字,還有一個(gè)空格x,移動(dòng)空格的位置,直到移到1~8按順序排好,輸出移動(dòng)的序列。
?
解法:看到題果斷寫了個(gè)廣搜……然后T了……百度了一下說廣搜雖然慢了點(diǎn)但是也是可以過的嘛……默默看了眼自己代碼……唔……好像他們都不是用string路徑的……
實(shí)在懶得改了,學(xué)個(gè)新做法吧,哦吼吼吼這個(gè)A*看起來很神奇啊……學(xué)一下學(xué)一下
600ms+過了……嗯……跟別人廣搜一個(gè)時(shí)間啊……_(:з」∠)_實(shí)在不想改記路徑的方法啊……
A*我覺得就是一個(gè)更聰明的廣搜……每個(gè)狀態(tài)的權(quán)值為每個(gè)數(shù)到最終狀態(tài)的曼哈頓距離之和加上已走過的步長,用優(yōu)先隊(duì)列維護(hù)……
還有就是每個(gè)狀態(tài)序列可以轉(zhuǎn)換成一個(gè)排列的id……漲姿勢了0v0
?
代碼:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string> #include<string.h> #include<math.h> #include<limits.h> #include<time.h> #include<stdlib.h> #include<map> #include<queue> #include<set> #include<stack> #include<vector> #define LL long longusing namespace std;int fac[] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880 }; int order(vector <int> v) {int i, j, temp, num;num = 0;for (i = 0; i < 8; i++) {temp = 0;for (j = i + 1; j < 9; j++) {if (v[j] < v[i])temp++;}num += fac[v[i] -1] * temp;}return num; } bool vis[400000]; int dir1[4][2] = {-1, 0, 1, 0, 0, -1, 0, 1}; char dir2[] = "udlr"; struct node {vector <int> v;string path;node(vector <int> tv, string tpath){v = tv;path = tpath;}node() {}bool operator < (const node &tmp) const{int sum1 = 0, sum2 = 0;for(int i = 0; i < 9; i++)sum1 += abs((v[i] - 1) / 3 - i / 3) + abs((v[i] - 1) % 3 - i % 3);for(int i = 0; i < 9; i++)sum2 += abs((tmp.v[i] - 1) / 3 - i / 3) + abs((tmp.v[i] - 1) % 3 - i % 3);return sum1 + path.size() > sum2 + tmp.path.size();} }; string bfs(vector <int> st) {memset(vis, 0, sizeof vis);vis[order(st)] = 1;priority_queue <node> q;q.push(node(st, ""));while(!q.empty()){node tmp = q.top();if(order(tmp.v) == 0) return tmp.path;q.pop();int sx, sy;for(int i = 0; i < 3; i++)for(int j = 0; j < 3; j++)if(tmp.v[i * 3 + j] == 9){sx = i;sy = j;}for(int i = 0; i < 4; i++){int tx = sx + dir1[i][0], ty = sy + dir1[i][1];if(tx < 0 || tx > 2 || ty < 0 || ty > 2) continue;swap(tmp.v[tx * 3 + ty], tmp.v[sx * 3 + sy]);int id = order(tmp.v);if(!vis[id]){vis[id] = 1;q.push(node(tmp.v, tmp.path + dir2[i]));}swap(tmp.v[tx * 3 + ty], tmp.v[sx * 3 + sy]);}}return "unsolvable"; } int main() {char input[2];while(~scanf("%s", input)){vector <int> v;if(input[0] == 'x')v.push_back(9);elsev.push_back(input[0] - '0');for(int i = 0; i < 8; i++){scanf("%s", input);if(input[0] == 'x')v.push_back(9);elsev.push_back(input[0] - '0');}int sum = 0;for(int i = 1; i < 9; i++)for(int j = 0; j < i; j++)if(v[i] != 9 && v[j] != 9 && v[i] < v[j]) sum++;if((sum & 1) == 0)cout << bfs(v) << endl;elseputs("unsolvable1");}return 0; }
轉(zhuǎn)載于:https://www.cnblogs.com/Apro/p/4807512.html
總結(jié)
以上是生活随笔為你收集整理的POJ 1077 Eight的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 四则运算心得
- 下一篇: 软件观念革命:交互设计精髓_2021年中