标签:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef long long LL; 5 6 /** 7 学习:(1)康托展开的使用 8 (2)路径记录 9 ? A* 10 ? 双向bfs 11 */ 12 13 int t[9],s[9]; 14 bool vis[362880 + 10]; 15 char ans[362880 + 10][42]; 16 int fac[]={1,1,2,6,24,120,720,5040,40320}; 17 void cantor(int *s, LL num, int k){//康托展开,把一个数字num展开成一个数组s,k是数组长度 18 int t; 19 bool h[k];//0到k-1,表示是否出现过 20 memset(h, 0, sizeof(h)); 21 for(int i = 0; i < k; i ++){ 22 t = num / fac[k-i-1]; 23 num = num % fac[k-i-1]; 24 for(int j = 0, pos = 0; ; j ++, pos ++){ 25 if(h[pos]) j --; 26 if(j == t){ 27 h[pos] = true; 28 s[i] = pos + 1; 29 break; 30 } 31 } 32 } 33 } 34 void inv_cantor(int *s, LL &num, int k){//康托逆展开,把一个数组s换算成一个数字num 35 int cnt; 36 num = 0; 37 for(int i = 0; i < k; i ++){ 38 cnt = 0; 39 for(int j = i + 1; j < k; j ++){ 40 if(s[i] > s[j]) cnt ++;//判断几个数小于它 41 } 42 num += fac[k-i-1] * cnt; 43 } 44 } 45 46 struct Node{ 47 int key,cnt,x,y; // x,y 表示 9 所在的位置 48 Node(int _key,int _x,int _y,int _cnt):key(_key),cnt(_cnt),x(_x),y(_y){} 49 }; 50 51 void init(){ 52 53 ll skey; 54 memset(vis,false,sizeof(vis)); 55 memset(ans,0,sizeof(ans)); 56 57 for(int i = 1 ; i <= 9 ; i ++) s[i-1] = i; 58 inv_cantor(s,skey,9); 59 vis[skey] = true; 60 ans[skey][0] = ‘\0‘; 61 queue<Node> q; 62 q.push(Node{skey,2,2,0}); 63 64 while(!q.empty()){ 65 Node tmp = q.front(); q.pop(); 66 ll nowkey = tmp.key,newkey; 67 int cnt = tmp.cnt, nowx = tmp.x , nowy = tmp.y; 68 int nowarr[10]; 69 cantor(nowarr,nowkey, 9); 70 71 if(nowx >= 1){ 72 swap(nowarr[nowx*3+nowy],nowarr[(nowx-1)*3+nowy]); 73 inv_cantor(nowarr, newkey, 9); 74 if(!vis[newkey]){ 75 vis[newkey] = true; 76 for(int i = 0 ; i < cnt ; i ++) ans[newkey][i]=ans[nowkey][i]; 77 ans[newkey][cnt] = ‘d‘; 78 ans[newkey][cnt+1] = ‘\0‘; 79 q.push(Node{newkey,nowx-1,nowy,cnt+1}); 80 } 81 swap(nowarr[nowx*3+nowy],nowarr[(nowx-1)*3+nowy]); 82 } 83 84 if(nowy >= 1){ 85 swap(nowarr[nowx*3+nowy],nowarr[nowx*3+nowy-1]); 86 inv_cantor(nowarr, newkey, 9); 87 if(!vis[newkey]){ 88 vis[newkey] = true; 89 for(int i = 0 ; i < cnt ; i ++) ans[newkey][i]=ans[nowkey][i]; 90 ans[newkey][cnt] = ‘r‘; 91 ans[newkey][cnt+1] = ‘\0‘; 92 q.push(Node{newkey,nowx,nowy-1,cnt+1}); 93 } 94 swap(nowarr[nowx*3+nowy],nowarr[nowx*3+nowy-1]); 95 } 96 if(nowx <= 1){ 97 swap(nowarr[nowx*3+nowy],nowarr[(nowx+1)*3+nowy]); 98 inv_cantor(nowarr, newkey, 9); 99 if(!vis[newkey]){ 100 vis[newkey] = true; 101 for(int i = 0 ; i < cnt ; i ++) ans[newkey][i]=ans[nowkey][i]; 102 ans[newkey][cnt] = ‘u‘; 103 ans[newkey][cnt+1] = ‘\0‘; 104 q.push(Node{newkey,nowx+1,nowy,cnt+1}); 105 } 106 swap(nowarr[nowx*3+nowy],nowarr[(nowx+1)*3+nowy]); 107 } 108 if(nowy <= 1){ 109 swap(nowarr[nowx*3+nowy],nowarr[nowx*3+nowy+1]); 110 inv_cantor(nowarr, newkey, 9); 111 if(!vis[newkey]){ 112 vis[newkey] = true; 113 for(int i = 0 ; i < cnt ; i ++) ans[newkey][i]=ans[nowkey][i]; 114 ans[newkey][cnt] = ‘l‘; 115 ans[newkey][cnt+1] = ‘\0‘; 116 q.push(Node{newkey,nowx,nowy+1,cnt+1}); 117 } 118 swap(nowarr[nowx*3+nowy],nowarr[nowx*3+nowy+1]); 119 } 120 121 } 122 } 123 124 void solve(){ 125 126 ll tkey; 127 inv_cantor(t,tkey,9); 128 129 if(!vis[tkey]) puts("unsolvable"); 130 else{ 131 int len = strlen(ans[tkey]); 132 for(int i = len - 1 ; i >= 0 ; i --) putchar(ans[tkey][i]); 133 puts(""); 134 } 135 } 136 137 int main(){ 138 string str; 139 char x; 140 int cnt; 141 init(); 142 while(getline(cin,str)){ 143 stringstream ss(str); 144 int cnt = 0; 145 while(ss >> x){ 146 if(x == ‘x‘) t[cnt++] = 9; 147 else t[cnt++] = x - ‘0‘; 148 } 149 solve(); 150 } 151 return 0; 152 }
标签:
原文地址:http://www.cnblogs.com/zstu-jack/p/5468406.html