1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 x
1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 5 6 7 8 5 6 7 8 5 6 7 8 5 6 7 8 9 x 10 12 9 10 x 12 9 10 11 12 9 10 11 12 13 14 11 15 13 14 11 15 13 14 x 15 13 14 15 x r-> d-> r->
2 3 4 1 5 x 7 6 8
ullddrurdllurdruldr
题目大意:经典题,不解释。
题目分析:杭电的测试数据比poj强,poj乱搞也能过,hdu卡单向bfs,双向比较保险,高级点的话就A*吧。
传说此题不做人生不完整。。。
详情请见代码:
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 1000005;//poj4048K 0MS... long fac[] = {1,1,2,6,24,120,720,5040,40320,362880}; int flag[2][363000];//记录前驱后继 char op[2][363000];//记录路径 bool ok; struct node { int val,step,pos; char state[9]; }ss,now; int start,end; struct que { struct node t[N]; int head,tail; void init() { head = tail = 0; } bool empty() { return head == tail; } void push(struct node a) { t[tail] = a; tail ++; if(tail >= N) tail -= N; } struct node top() { return t[head]; } void pop() { head ++; if(head >= N) head -= N; } }q[2]; int contor() { int i,j; int tmp,num; num = 0; for(i = 0;i < 9;i ++) { tmp = 0; for(j = i + 1;j < 9;j ++) if(ss.state[j] < ss.state[i]) tmp ++; num += fac[9 - i - 1] * tmp; } return num; } void output(int cur) { if(cur == start) return; output(flag[0][cur]); putchar(op[0][cur]); } void print() { int i,root; output(ss.val);//从起点到相遇点的路径输出 root = ss.val; do { switch(op[1][root]) { case 'u':putchar('d');break; case 'd':putchar('u');break; case 'l':putchar('r');break; case 'r':putchar('l');break; } root = flag[1][root]; }while(root != end);//从相遇点到终点的路径输出,注意反向 putchar(10); } void dbfs() { int i,j; q[0].init(); q[1].init(); ss.step = 0; q[0].push(ss); ss.val = 0; for(i = 0;i < 9;i ++) ss.state[i] = '1' + i; ss.pos = 8; q[1].push(ss); flag[1][end] = end; flag[0][start] = start; j = 0; while(!q[0].empty() && !q[1].empty()) { for(i = 0;i < 2;i ++) { while(!q[i].empty() && q[i].top().step == j) { now = q[i].top(); //printf("%d %d %d\n",i,now.step,now.val); //system("pause"); q[i].pop(); if(now.pos > 2)//up { ss = now; ss.step ++; ss.state[ss.pos] ^= ss.state[ss.pos - 3] ^= ss.state[ss.pos] ^= ss.state[ss.pos - 3]; ss.pos -= 3; ss.val = contor(); if(flag[i][ss.val] == -1) { flag[i][ss.val] = now.val; op[i][ss.val] = 'u'; if(flag[1 - i][ss.val] != -1) { print(); return; } q[i].push(ss); } } if(now.pos < 6)//down { ss = now; ss.step ++; ss.state[ss.pos] ^= ss.state[ss.pos + 3] ^= ss.state[ss.pos] ^= ss.state[ss.pos + 3]; ss.pos += 3; ss.val = contor(); if(flag[i][ss.val] == -1) { flag[i][ss.val] = now.val; op[i][ss.val] = 'd'; if(flag[1 - i][ss.val] != -1) { print(); return; } q[i].push(ss); } } if(now.pos % 3)//left { ss = now; ss.step ++; ss.state[ss.pos] ^= ss.state[ss.pos - 1] ^= ss.state[ss.pos] ^= ss.state[ss.pos - 1]; ss.pos --; ss.val = contor(); if(flag[i][ss.val] == -1) { flag[i][ss.val] = now.val; op[i][ss.val] = 'l'; if(flag[1 - i][ss.val] != -1) { print(); return; } q[i].push(ss); } } if(now.pos % 3 != 2)//right { ss = now; ss.step ++; ss.state[ss.pos] ^= ss.state[ss.pos + 1] ^= ss.state[ss.pos] ^= ss.state[ss.pos + 1]; ss.pos ++; ss.val = contor(); if(flag[i][ss.val] == -1) { flag[i][ss.val] = now.val; op[i][ss.val] = 'r'; if(flag[1 - i][ss.val] != -1) { print(); return; } q[i].push(ss); } } } } j ++; } //printf("out loop\n"); printf("unsolvable\n"); } int main() { char s[3]; while(scanf("%s",s) != EOF) { ss.state[0] = s[0]; if(ss.state[0] == 'x') { ss.state[0] = '9'; ss.pos = 0; } for(int i = 1;i < 9;i ++) { scanf("%s",s); if(s[0] == 'x') { s[0] = '9'; ss.pos = i; } ss.state[i] = s[0]; } ss.val = contor(); start = ss.val; end = 0; int so = 0; for(int ii = 0;ii < 9;ii ++)//逆序数偶数才有解,不包括空格!! { if(ss.state[ii] == '9') continue; for(int jj = 0;jj < ii;jj ++) { if(ss.state[jj] == '9') continue; if(ss.state[jj] < ss.state[ii]) so ++; } } //printf("%d\n",so); if(so % 2) { printf("unsolvable\n"); continue; } memset(flag,-1,sizeof(flag)); dbfs(); } return 0; } //hdu421MS 4092K //poj4052K 16MS