POJ - 1077 - Eight(bfs)
题目链接:https://vjudge.net/problem/POJ-1077
题目大意:八数码,问你能不能把当前状态转换成12345678x,可以就输出转换步骤,不行就输出unsolvable。
经典的八数码题,只是在普通的bfs基础上用上了康托展开,用map,string的可能会t
#include<set> #include<map> #include<list> #include<stack> #include<queue> #include<cmath> #include<cstdio> #include<cctype> #include<string> #include<vector> #include<climits> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define endl '\n' #define max(a, b) (a > b ? a : b) #define min(a, b) (a < b ? a : b) #define mst(a) memset(a, 0, sizeof(a)) #define IOS ios::sync_with_stdio(false) #define _test printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n") using namespace std; typedef long long ll; typedef pair<int, int> P; typedef pair<ll, ll> P2; const double pi = acos(-1.0); const double eps = 1e-7; const ll MOD = 1000000007LL; const int INF = 0x3f3f3f3f; const int _NAN = -0x3f3f3f3f; const int NIL = -1; template<typename T> void read(T &x){ x = 0;char ch = getchar();ll f = 1; while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();} while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f; } const int maxn = 1e6+10; int vis[maxn], start[9], ed[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; const int dir[4][2] = {1,0, -1,0, 0,-1, 0,1}; const int fact[10] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880}; struct Q { int x, y, kase, state[9]; char ans[30]; }; int cantor(int num[], int n) { //用康托展开计算判断当前状态 int sum = 0; for (int i = 0; i<n; ++i) { int cnt = 0; for (int j = i+1; j<n; ++j) if (num[i]>num[j]) ++cnt; sum += cnt*fact[n-i-1]; } return vis[sum] ? false : vis[sum] = true; } bool checker(int* num) { //和目标状态比较 for (int i = 0; i<9; ++i) if (num[i]!=ed[i]) return false; return true; } Q bfs(int w) { queue<Q> qe; Q t = {w/3, w%3}; //转换成坐标形式 cantor(start, 9); t.kase = 0; memcpy(t.state, start, sizeof(start)); qe.push(t); while(!qe.empty()) { t = qe.front(); qe.pop(); if (checker(t.state)) return t; for (int i = 0; i<4; ++i) { int xx = t.x+dir[i][0], yy = t.y+dir[i][1]; if (xx>=0&&xx<3&&yy>=0&&yy<3) { Q t2 = t; t2.x = xx, t2.y = yy; t2.ans[t2.kase++] += "dulr"[i]; swap(t2.state[t2.x*3+t2.y], t2.state[t.x*3+t.y]); if (checker(t2.state)) return t2; if (cantor(t2.state, 9)) qe.push(t2); } } } t = {-1, -1}; return t; } int main(void) { char s[2]; int pos; for (int i = 0; i<9; ++i) { scanf("%s", s); if (s[0]=='x') s[0] = '9', pos=i; //记录下起始位置 start[i] = s[0]-'0'; } Q res = bfs(pos); if (res.x == -1) printf("unsolvable\n"); else printf("%s\n", res.ans); return 0; }