bnuoj 1071 拼图++(BFS+康拓展开)
http://www.bnuoj.com/bnuoj/problem_show.php?pid=1071
【题意】:经过四个点的顺逆时针旋转,得到最终拼图
【题解】:康拓展开+BFS,注意先预处理,得到所有状态,然后用hash来调用存在的状态
【code】:
1 #include <iostream> 2 #include <stdio.h> 3 #include <queue> 4 #include <string.h> 5 6 using namespace std; 7 #define N 363000 8 9 struct Nod 10 { 11 int b[10]; 12 int pos; 13 }nd1,nd2; 14 15 int fac[] = {1,1,2,6,24,120,720,5040,40320,362880}; //康拓展开用到的数组 16 //康托展开: 17 int cantor(int* a, int k) 18 { 19 int i, j, tmp, num = 0; 20 for (i = 0; i < k; i++) { 21 tmp = 0; 22 for (j = i + 1; j < k; j++) 23 if (a[j] < a[i]) 24 tmp++; 25 num += fac[k - i - 1] * tmp; 26 } 27 return num; 28 } 29 30 int mark[N],pre[N]; 31 char dir[N]; 32 int cx[]={0,0,1,1}; 33 int cy[]={0,1,1,0}; 34 35 void exchange(int *a,int x,int y,int n) //旋转 36 { 37 int temp; 38 if(n%2) 39 { 40 temp = a[3*x+y]; 41 a[3*x+y] = a[3*x+y+1]; 42 a[3*x+y+1] = a[3*(x+1)+y+1]; 43 a[3*(x+1)+y+1] = a[3*(x+1)+y]; 44 a[3*(x+1)+y] = temp; 45 } 46 else 47 { 48 temp = a[3*(x+1)+y]; 49 a[3*(x+1)+y] = a[3*(x+1)+y+1]; 50 a[3*(x+1)+y+1] = a[3*x+y+1]; 51 a[3*x+y+1] = a[3*x+y]; 52 a[3*x+y] = temp; 53 } 54 } 55 56 void bfs(int *b) //广度优先搜索 57 { 58 queue<Nod> q; 59 memset(mark,0,sizeof(mark)); 60 memset(pre,0,sizeof(pre)); 61 memcpy(nd1.b,b,sizeof(int)*10); 62 int i,temp; 63 temp = cantor(b,9); 64 mark[temp] = 1; 65 nd1.pos = temp; 66 q.push(nd1); 67 while(!q.empty()) 68 { 69 nd2 = q.front(); 70 q.pop(); 71 for(i=0;i<8;i++) 72 { 73 memcpy(nd1.b,nd2.b,sizeof(int)*10); 74 exchange(nd1.b,cx[i/2],cy[i/2],i); 75 temp = cantor(nd1.b,9); 76 if(mark[temp]!=1) 77 { 78 mark[temp] = 1; 79 pre[temp] = pre[nd2.pos]+1; 80 nd1.pos = temp; 81 q.push(nd1); 82 } 83 } 84 } 85 } 86 87 int main() 88 { 89 char str[5]; 90 int a[10],b[10]={1,2,3,4,5,6,7,8,9},c[10],hash[12]; 91 bfs(b); 92 int t; 93 scanf("%d",&t); 94 while(t--) 95 { 96 int i; 97 for(i=0;i<9;i++) 98 { 99 scanf("%d",a+i); 100 hash[a[i]] = i+1; //hash 101 } 102 for(i=0;i<9;i++) 103 { 104 scanf("%d",c+i); 105 c[i] = hash[c[i]]; 106 } 107 int temp = cantor(c,9); 108 printf("Number Of Move(s) Needed: %d\n",pre[temp]); 109 } 110 return 0; 111 }