Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
双向搜索0MS YES#include <iostream> #include <cstring> #define N 362881 using namespace std; int state[N];//为1时正向到达,-1为逆向到达 int v[9], step[N]; const int fact[9] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320}; const int move[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; struct node { int num; int pre; int predir; int nextdir; int next; }q[N]; int fabs(int a) { if(a<0) return -a; return a; } int canto()//康托展开后面的数全排列 { int j, i, tmp; int ans; for (ans = 1, i = 0; i < 9; i++) { for (tmp = v[i] - 1, j = 0; j < i; j++) tmp -= (v[j] < v[i]); ans = ans + tmp * fact[8 - i]; } return ans; } void toArray(int num) { int i = 8; while (num) { v[i--] = num % 10; num /= 10; } } int toNum()//将数组换算为数字 { int i; int ans = 0; for (i = 0; i < 9; i++) ans =ans*10 + v[i]; return ans; } int BFS() { memset(state, false, sizeof(state)); int head, tail, val; int xx, xy, i, tx, ty, tmp, pos1, pos2; head = tail = 1; node p;//开始的状态 p.num = toNum(); p.pre = -1;//没有开始值设为-1 p.next=0;//0代表没有意义 p.predir = -1; p.nextdir=0;//0代表无意义 val = canto(); state[val] =1; if(123456789==p.num) return -2; node last;//最后的状态 last.num=123456789; last.next=-1; last.pre=0;//0代表无意义 last.predir=0;//0代表无意义 last.nextdir=-1; q[tail++] = p; q[tail++]=last; state[1] =-2; while (head < tail)//队列非空 { p = q[head]; //取出头指针 // printf("%d\n",p.num); toArray(p.num); val = canto(); for (i = 0; i < 9; i++)//找到x的位置 if (v[i] == 9) break; xy = i / 3; xx = i % 3; //move tx = xx; ty = xy; for (i = 0; i < 4; i++) { tx += move[i][0]; ty += move[i][1]; if (tx >= 0 && tx < 3 && ty >= 0 && ty < 3) { pos1 = tx + ty * 3; pos2 = xx + xy * 3; //将值交换 tmp = v[pos1]; v[pos1] = v[pos2]; v[pos2] = tmp; val = canto();//计算新值 if (0==q[head].pre&&0==state[val])//head点逆向到达且没有标记过 { state[val] =-tail;//标记为逆向到达 p.num = toNum(); p.pre =0; p.predir =0; p.next=head; p.nextdir=i; q[tail++] = p; } else if(0==q[head].pre&&state[val]>0)//逆向已到达过 { q[fabs(state[val])].next=head; q[fabs(state[val])].nextdir=i; return fabs(state[val]); } else if (0==q[head].next&&0==state[val])//head点正向到达没有标记过 { state[val] = tail;//标记为以到达过 p.num = toNum(); p.pre =head; p.predir =i; p.next=0; p.nextdir=0; q[tail++] = p; } else if(0==q[head].next&&state[val]<0)//head点正向到达新点逆向已到达过 { q[fabs(state[val])].pre=head; q[fabs(state[val])].predir=i; return fabs(state[val]); } // printf("p.num=%d p.pre=%d p.pre=%d p.predir=%d p.nextdir=%d\n",p.num,p.pre,p.predir ,p.next, p.nextdir); tmp = v[pos2];//恢复未移动时的数据 v[pos2] = v[pos1]; v[pos1] = tmp; } tx = xx; ty = xy; } head++; } return -1; } void print(int i) { int pos = 0; int tempi=i; // printf("i=%d\n",i); // printf("p.num=%d p.pre=%d p.pre=%d p.predir=%d p.nextdir=%d\n",q[i].num,q[i].pre,q[i].predir ,q[i].next, q[i].nextdir); while (q[i].pre != -1) { step[pos++] = q[i].predir; i = q[i].pre; } for (i = pos - 1; i >= 0; i--) { switch (step[i]) { case 0: cout << 'r'; break; case 1: cout << 'd'; break; case 2: cout << 'l'; break; case 3: cout << 'u'; break; } } i=tempi; while (q[i].next != -1) { if(0==q[i].nextdir) cout << 'l'; else if(1==q[i].nextdir) cout << 'u'; else if(2==q[i].nextdir) cout << 'r'; else if(3==q[i].nextdir) cout << 'd'; i = q[i].next; } cout<<endl; } int main() { int i; int tmp; char c; for (i = 0; i < 9; i++) { cin >> c; if (c == 'x') v[i] = 9; else v[i] = c - '0'; } tmp = BFS(); if (-1==tmp ) cout << "unsolvable"<<endl; else if(-2==tmp) cout<<endl; else print(tmp); //system("pause"); return 0; } Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator