BZOJ 1054: [HAOI2008]移动玩具(bfs)
题面:
https://www.lydsy.com/JudgeOnline/problem.php?id=1054
题解:
将每一种状态十六位压成二进制,然后bfs。。不解释。。
p.s.注意特判初始==目标;
代码:
#include<bits/stdc++.h> using namespace std; const int mx[5]={0,1,-1,0,0},my[5]={0,0,0,-1,1}; int g[6][6],last,ans,vis[1000010]; char ch[6][6]; struct node{ int w,dep; }; queue<node>q; void back(int x){ for(int i=4;i;i--) for(int j=4;j;j--) g[i][j]=x&1,x>>=1; } int to(){ int sum=0; for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) sum<<=1,sum+=g[i][j]; return sum; } void bfs(){ while(!q.empty()){ node h=q.front(); q.pop(); back(h.w); for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) if(g[i][j]) for(int k=1;k<=4;k++){ int xx=i+mx[k],yy=j+my[k]; if(xx>0&&xx<5&&yy>0&&yy<5&&!g[xx][yy]){ g[xx][yy]^=1,g[i][j]^=1; int tt=to(); if(tt==last){ ans=h.dep+1; return ; } if(!vis[tt]) q.push((node){tt,h.dep+1}),vis[tt]=1; g[xx][yy]^=1,g[i][j]^=1; } } } } int main(){ for(int i=1;i<=4;i++) scanf("%s",ch[i]+1); for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) g[i][j]=ch[i][j]-'0'; int tt=to(); q.push((node){tt,0}); vis[tt]=1; for(int i=1;i<=4;i++) scanf("%s",ch[i]+1); for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) g[i][j]=ch[i][j]-'0'; last=to(); if(last==tt){ printf("0"); return 0; } bfs(); printf("%d",ans); return 0; }