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;    
}

 

posted @ 2018-04-08 13:06  Jack_the_Ripper  阅读(152)  评论(2编辑  收藏  举报