考察:bfs
思路:
考虑过IDA*,但是搜索层数不一定很浅.然后就是A*,想法是所有不在位置上的数的个数(空白部分不计).但是做之前为了搞懂题意看了讨论区,结果暴雷...看到题解大字标题bfs+hash.....我错了,以后还是自己搞懂题意555
普通的bfs就可以过.可以将数组定义为结构体属性,然后普通的bfs.或者用字符串.但是注意我们不是用"11","12"的字符串将所有数字连接.而是将数字看成ASCII码值.所对应的字符连接.这样就保证字符串总长度为32.(但也可以用"11"数字标识,只要把空白符用一个两位字符标识即可.)
1 #include <iostream> 2 #include <cstring> 3 #include <unordered_map> 4 #include <string> 5 #include <map> 6 #include <queue> 7 using namespace std; 8 const int N = 5,M = 10; 9 string ed; 10 int tar[N][M],mp[N][M]; 11 unordered_map<string,int> um; 12 void init() 13 { 14 int fl = 11; 15 for(int i=1;i<=4;i++) 16 for(int j=1;j<=7;j++) 17 { 18 tar[i][j] = fl++; 19 if(j==7) fl = (i+1)*10+1; 20 } 21 tar[1][8] = tar[2][8] = tar[3][8] = tar[4][8] = 1; 22 for(int i=1;i<=4;i++) 23 for(int j=1;j<=8;j++) ed+=tar[i][j]; 24 } 25 void prework() 26 { 27 for(int i=1;i<=4;i++) 28 for(int j=2;j<=8;j++) 29 if(mp[i][j]%10==1) 30 { 31 int x = mp[i][j]; 32 mp[x/10][1] = x; 33 mp[i][j] = 1; 34 } 35 } 36 int get(int x,string s) 37 { 38 for(int i=0;i<s.size();i++) 39 if(s[i]==x+1) return i; 40 return -1; 41 } 42 int bfs() 43 { 44 string st = ""; 45 for(int i=1;i<=4;i++) 46 for(int j=1;j<=8;j++) st+=mp[i][j]; 47 um[st] = 0; 48 queue<string> q; 49 q.push(st); 50 while(q.size()) 51 { 52 string it = q.front(); 53 q.pop(); 54 if(it==ed) return um[it]; 55 for(int i=0;i<32;i++) 56 if(it[i]==1) 57 { 58 int idx = get(it[i-1],it); 59 string v = it; 60 swap(v[idx],v[i]); 61 if(um.count(v)) continue; 62 um[v] = um[it]+1; 63 q.push(v); 64 } 65 } 66 return -1; 67 } 68 int main() 69 { 70 init(); 71 int T; 72 scanf("%d",&T); 73 while(T--) 74 { 75 um.clear(); 76 memset(mp,0,sizeof mp); 77 for(int i=1;i<=4;i++) 78 for(int j=2;j<=8;j++) scanf("%d",&mp[i][j]); 79 prework(); 80 printf("%d\n",bfs()); 81 } 82 return 0; 83 }