由结论可以知道逆序对为奇数的时候无解,f为估值函数,计算曼哈顿距离。
想用康托展开写,但多状态数码问题用数组存储状态不够,有TLE的风险,还是A*吧!
吃一个tomato宣告今日...不知道结不结束
#include <iostream> #include <vector> #include <queue> #include <unordered_map> using namespace std; const int dx[] = {-1,0,1,0},dy[] = {0,1,0,-1}; const char op[] = "urdl"; typedef pair <int,string> pii; char ch; string start,s; int f (string state) { int ans = 0; for (int i = 0;i < 9;i++) { if (state[i] == 'x') continue; int t = state[i] - '1'; ans += abs (i / 3 - t / 3) + abs (i % 3 - t % 3); } return ans; } string Astar () { string end = "12345678x"; unordered_map <string,int> dist; unordered_map <string,pair <char,string>> prev; priority_queue <pii,vector <pii>,greater <pii>> heap; dist[start] = 0; heap.push ({f(start),start}); while (!heap.empty ()) { auto t = heap.top (); heap.pop (); string state = t.second; if (state == end) break; int x,y; for (int i = 0;i < 9;i++) { if (state[i] == 'x') { x = i / 3,y = i % 3; break; } } string source = state; for (int i = 0;i < 4;i++) { int a = x + dx[i],b = y + dy[i]; if (a < 0 || a > 2 || b < 0 || b > 2) continue; swap (state[a*3+b],state[x*3+y]); if (!dist.count (state) || dist[state] > dist[source] + 1) { dist[state] = dist[source] + 1; prev[state] = {op[i],source}; heap.push ({dist[state] + f(state),state}); } state = source; } } string ans; while (end != start) { ans = prev[end].first + ans; end = prev[end].second; } return ans; } signed main () { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); for (int i = 0;i < 9;i++) { cin >> ch; start += ch; if (ch != 'x') s += ch; } int cnt = 0; for (int i = 0;i < 8;i++) { for (int j = i;j < 8;j++) { if (s[i] > s[j]) cnt++; } } if (cnt & 1) puts ("unsolvable"); else cout << Astar () << endl; return 0; }
标签:dist,string,int,1077,BFS,++,state,Eight,ans From: https://www.cnblogs.com/accbulb/p/18006461