【双向bfs】2017多校训练十 HDU 6171 Admiral
【题意】
- 现在给出一个三角矩阵,如果0编号的在点(x,y)的话,可以和(x+1,y),(x-1,y),(x+1,y+1),(x-1,y-1)这些点进行交换。
- 我们每一次只能对0点和其他点进行交换。问最少步数,使得最终变成:
0
1 1
2 2 2
3 3 3 3
4 4 4 4 4
5 5 5 5 5 5
【思路】
【AC】
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned long long ull; 5 const int inf=0x3f3f3f3f; 6 struct node 7 { 8 int val[6][6]; 9 int tp; 10 int r; 11 int c; 12 int step; 13 }s,t; 14 15 ull Hash(node t) 16 { 17 ull tmp=0; 18 for(int i=0;i<6;i++) 19 { 20 for(int j=0;j<=i;j++) 21 { 22 tmp=tmp*6+t.val[i][j]; 23 } 24 } 25 return tmp; 26 } 27 queue<node> Q; 28 map<ull,int> book[2]; 29 int dir[4][2]={{1,0},{-1,0},{1,1},{-1,-1}}; 30 int bfs(node s,node t) 31 { 32 while(!Q.empty()) Q.pop(); 33 book[0].clear(); 34 book[1].clear(); 35 s.step=t.step=0; 36 s.tp=0;t.tp=1; 37 book[s.tp][Hash(s)]=0; 38 book[t.tp][Hash(t)]=0; 39 Q.push(s);Q.push(t); 40 while(!Q.empty()) 41 { 42 node q=Q.front(),e;Q.pop(); 43 ull tmp=Hash(q); 44 if(book[!q.tp].count(tmp)) 45 { 46 if(book[!q.tp][tmp]+q.step<=20) 47 return book[!q.tp][tmp]+q.step; 48 else continue; 49 } 50 if(q.step>=10) continue; 51 for(int i=0;i<4;i++) 52 { 53 e=q; 54 e.r+=dir[i][0]; 55 e.c+=dir[i][1]; 56 if(e.r<0||e.r>=6||e.c<0||e.c>=6||e.c>e.r) continue; 57 swap(e.val[e.r][e.c],e.val[q.r][q.c]); 58 ull tmp=Hash(e); 59 if(book[e.tp].count(tmp)) continue; 60 book[e.tp][tmp]=++e.step; 61 Q.push(e); 62 } 63 } 64 return inf; 65 } 66 int main() 67 { 68 int T; 69 scanf("%d",&T); 70 while(T--) 71 { 72 for(int i=0;i<6;i++) 73 { 74 for(int j=0;j<=i;j++) 75 { 76 scanf("%d",&s.val[i][j]); 77 if(s.val[i][j]==0) 78 { 79 s.r=i;s.c=j; 80 } 81 t.val[i][j]=i; 82 } 83 } 84 t.r=t.c=0; 85 int ans=bfs(s,t); 86 if(ans==inf) puts("too difficult"); 87 else printf("%d\n",ans); 88 } 89 return 0; 90 }