http://acm.hdu.edu.cn/showproblem.php?pid=1043
因为结果都是“12345678x”,目标状态固定,所以可以列举所有的可能,然后用哈希表标志,然后直接调用
/* PKUoj Source Code Problem: 1077 User: 297752873 Memory: 6728K Time: 313MS Language: C Result: Accepted Source Code */ #include<stdio.h> #include<stdlib.h> #include<string.h> #define QueueSize 370000 int f[8] = {1, 2, 6, 24, 120, 720, 5040, 40320};//用于全排列的哈希函数的构建 char end[10],ch[4]={'d','u','r','l'};//开始和结束的状态 int ans[400000],hash[400000];//开始和结束的点 struct eight { char str[10];//结点矩阵 int k ;//空格的位置 int fx;//移动的方向1表示上,2表示下, 3表示左,4表示右 int fa;//父节点 }s[370000]; typedef struct { int front; int rear; int count; int data[370000]; }CirQueue; CirQueue Q;//使用队列,队列里保存的是各状态的下标 void InitQueue(CirQueue *Q)//建队 { Q->front=Q->rear=0; Q->count=0; } int QueueEmpty(CirQueue *Q)//判队是否空 { return Q->count==0; } void EnQueue(CirQueue *Q,int x)//入队 { Q->count++; Q->data[Q->rear]=x; Q->rear=(Q->rear+1)%QueueSize; } int DeQueue(CirQueue *Q)//出队,并删除队首元素 { int temp; temp=Q->data[Q->front]; Q->count--; Q->front=(Q->front+1)%QueueSize; return temp; } int get_hash_code(char str[]) //计算全排列哈希值 { int i, j; int ret = 0, cnt; for(i = 1; i < 9; ++i) { cnt = 0; for(j = 0; j < i; ++j) if(str[j] > str[i]) cnt++; ret += cnt*f[i-1]; } return ret; } void print(int x)//若发现可完成,则利用父节点逐个输出 { //printf("find\n"); while (x!=s[x].fa) { printf("%c",ch[s[x].fx-1]); x=s[x].fa; } printf("\n"); } int bfs() { int w,k,has; char temp,a[10];//这些作为中间量 memset(hash,0,sizeof(hash)); has=get_hash_code("123456780"); s[has].fa=has;//第一个的父节点赋为自己 strcpy(s[has].str,"123456780"); s[has].k=8; hash[has]=1; InitQueue(&Q); /*if(strcmp(s[beginf].str,end)==0) { printf("lr\n"); return 0; }*/ EnQueue(&Q,has); while(!QueueEmpty(&Q)) { w=DeQueue(&Q);//取队首元素 /* if(strcmp(s[w].str,end)==0) { print(w); return 0; } */ strcpy(a,s[w].str); k=s[w].k;//保留空格的位置 if (k>=3)//可上移的 { temp=a[k];a[k]=a[k-3];a[k-3]=temp; has=get_hash_code(a); if (hash[has]==0) { strcpy(s[has].str,a); s[has].fx=1; s[has].fa=w; s[has].k=k-3; hash[has]=1; EnQueue(&Q,has); } temp=a[k];a[k]=a[k-3];a[k-3]=temp;//复原成原来的样子,以便下一个移动可以使用 } if (k%3!=0)//可左移的 { temp=a[k];a[k]=a[k-1];a[k-1]=temp; has=get_hash_code(a); if (hash[has]==0) { strcpy(s[has].str,a); s[has].fx=3; s[has].fa=w; s[has].k=k-1; hash[has]=1; EnQueue(&Q,has); } temp=a[k];a[k]=a[k-1];a[k-1]=temp; } if (k%3!=2)//可右移的 { temp=a[k];a[k]=a[k+1];a[k+1]=temp; has=get_hash_code(a); if (hash[has]==0) { strcpy(s[has].str,a); s[has].fx=4; s[has].fa=w; s[has].k=k+1; hash[has]=1; EnQueue(&Q,has); } temp=a[k];a[k]=a[k+1];a[k+1]=temp; } if (k<6)//可下移的 { temp=a[k];a[k]=a[k+3];a[k+3]=temp; has=get_hash_code(a); if (hash[has]==0) { strcpy(s[has].str,a); s[has].fx=2; s[has].fa=w; s[has].k=k+3; hash[has]=1; EnQueue(&Q,has); }temp=a[k];a[k]=a[k+3];a[k+3]=temp; } } } int main() { int i,j,m,l; bfs(); while(gets(end)!=NULL) { j=0; l=strlen(end); for(i=0;i<l;i++){ if(end[i]==' ')continue; if(end[i]=='x') { end[j]='0'; j++; }else end[j++]=end[i]; } end[j]='\0'; m=get_hash_code(end); //printf("%s \n",end); if(hash[m]) print(m); else printf("unsolvable\n"); // system("pause"); } return 0; }