bzoj 1054 移动玩具
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1054
题解:
瞎基本搜是没有希望的,还是正常的BFS比较靠谱
看出4*4的格子每行串在一起即是一个01串,可以用类似于状态压缩的思想解决,将其转化为十进制数,主要为了判断是否已经到了理想的状态
队列中存储状态,在BFS的时候取出队首,针对每一个棋子的四种移动产生新的状态,再入队处理即可
(有点搞不懂当时为什么要用“hash”来命名这种状态压缩……)
1 #include<cstdio> 2 #include<cstring> 3 int st,en,_x[]={0,0,0,-1,1},_y[]={0,1,-1,0,0}; 4 bool vis[65536]; 5 struct node 6 { 7 bool status[5][5]; 8 int dep; 9 }q[65536]; 10 inline int hash(bool a[5][5]) 11 { 12 int k=1,ans=0; 13 for(int i=1;i<=4;i++) 14 { 15 for(int j=1;j<=4;j++) 16 { 17 ans+=a[i][j]*k; 18 k<<=1; 19 } 20 } 21 return ans; 22 } 23 void init() 24 { 25 char temp[5]; 26 bool temp2[5][5]; 27 for(int i=1;i<=4;i++) 28 { 29 scanf("%s",temp+1); 30 for(int j=1;j<=4;j++) 31 { 32 q[1].status[i][j]=temp[j]-'0'; 33 } 34 } 35 for(int i=1;i<=4;i++) 36 { 37 scanf("%s",temp+1); 38 for(int j=1;j<=4;j++) 39 { 40 temp2[i][j]=temp[j]-'0'; 41 } 42 } 43 st=hash(q[1].status); 44 en=hash(temp2); 45 } 46 void bfs() 47 { 48 vis[st]=true; 49 int head=1,tail=2; 50 while(head<tail) 51 { 52 for(int i=1;i<=4;i++) 53 { 54 for(int j=1;j<=4;j++) 55 { 56 if(q[head].status[i][j]) 57 { 58 for(int k=1;k<=4;k++) 59 { 60 int x=i+_x[k],y=j+_y[k]; 61 if(q[head].status[x][y]||!x||!y||x>4||y>4)continue; 62 q[head].status[i][j]=false; 63 q[head].status[x][y]=true; 64 int hash_of_status=hash(q[head].status); 65 if(!vis[hash_of_status]) 66 { 67 if(hash_of_status==en) 68 { 69 printf("%d",q[head].dep+1); 70 return; 71 } 72 memcpy(q[tail].status,q[head].status,sizeof(q[tail].status)); 73 q[tail++].dep=q[head].dep+1; 74 vis[hash_of_status]=true; 75 } 76 q[head].status[i][j]=true; 77 q[head].status[x][y]=false; 78 } 79 } 80 } 81 } 82 head++; 83 } 84 } 85 int main() 86 { 87 init(); 88 if(st==en) 89 { 90 printf("0\n"); 91 return 0; 92 } 93 bfs(); 94 return 0; 95 }