POJ-1077 康托展开+BFS
前置知识
康托展开:
https://blog.csdn.net/qq_38701476/article/details/81003290
code(注释详解):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
| #include<cstdio> #include<cstring> #include<set> #include<stack> #include<cmath> #include<cstring> #include<string> #include<algorithm> #include<queue> #include<cstdlib> #include<iostream> #include<map> using namespace std; int fac[15]={1,1,2,6,24,120,720,5040,40320,362880}; string path; int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; char index[5]="udlr"; int aim=46234; bool visit[900005]; struct node{ int loc; int s[10]; string path; int hashval; }chess;
int cantor(int s[]) { int sum=0; for(int i=0;i<9;i++) { int cnt=0; for(int j=i+1;j<9;j++) { if(s[i]>s[j]) cnt++; } sum+=cnt*fac[8-i]; } return sum+1; }
bool bfs() { queue<node>q; node cur; node next; q.push(chess); visit[chess.hashval]=true; while(!q.empty()) { cur=q.front(); q.pop(); if(cur.hashval==aim) { path=cur.path; return true; } int x=cur.loc/3; int y=cur.loc%3; for(int i=0;i<4;i++) { int tempX=x+dir[i][0]; int tempY=y+dir[i][1];
if(tempX<0||tempY<0||tempX>2||tempY>2) continue; next=cur; next.loc=3*tempX+tempY; next.s[cur.loc]=next.s[next.loc]; next.s[next.loc]=0;
next.hashval=cantor(next.s);
if(next.hashval==aim) { next.path=cur.path+index[i]; path=next.path; return true; } if(visit[next.hashval]) continue; next.path=cur.path+index[i]; visit[next.hashval]=true; q.push(next); } } return false; } int main() { char ch[10]; memset(visit,false,sizeof visit); for(int i=0;i<9;i++) { scanf("%s",ch); if(ch[0]=='x') { chess.s[i]=0; chess.loc=i; } else { chess.s[i]=ch[0]-'0'; } } chess.hashval=cantor(chess.s); bool flag=bfs(); if(flag) cout<<path<<endl; else cout<<"unsolvable"<<endl; return 0; }
|