广搜优化

广搜对于“最少步数问题”非常好用,其优化在于判重,双向(队列)

我不管我开O2

例题1:

填涂颜色

由数字0组成的方阵中,有一任意形状闭合圈,闭合圈由数字1构成,围圈时只走上下左右4个方向。现要求把闭合圈内的所有空间都填写成2.

较简单

代码:

#include<bits/stdc++.h>
using namespace std;
int n;
int mx[4]={0,0,1,-1};
int my[4]={1,-1,0,0};
int a[35][35];
bool vis[35][35];
inline bool inside(int x,int y){
    return (1<=x&&x<=n)&&(1<=y&&y<=n);
}
inline void search(int x,int y){
    if(a[x][y]==1)return;
    for(int i=0;i<=3;i++){
        int nowx=x+mx[i];
        int nowy=y+my[i];
        if(!vis[nowx][nowy]&&inside(nowx,nowy)&&a[nowx][nowy]!=1){
            vis[nowx][nowy]=1;
            a[nowx][nowy]=0;
            search(nowx,nowy);
        }
    }
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            scanf("%d",&a[i][j]);
            if(!a[i][j]) a[i][j]=2;
        }
    }
    for(int i=1;i<=n;i++){
        if(!vis[1][i]){
            search(1,i);
            search(n,i);
            search(i,1);
            search(i,n);
        }
    }
    search(n,n);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++) printf("%d ",a[i][j]);
        cout<<endl;
    }
}

例题2:

移动玩具

在一个 4×4 的方框内摆放了若干个相同的玩具,某人想将这些玩具重新摆放成为他心中理想的状态,规定移动时只能将玩具向上下左右四个方向移动,并且移动的位置不能有玩具,请你用最少的移动次数将初始的玩具状态移动到目标状态。

代码:

#include<bits/stdc++.h>
using namespace std;
int tx[5]={1,-1,0,0};
int ty[5]={0,0,1,-1};
int ans; 
int f[4][4],pos[4][4],a[4][4],b,used[100010],dis[100010];
int dd(int pos1[4][4]){
    int kk=0;
    for(int i=0;i<4;i++){
        for(int j=0;j<4;j++)
            kk+=pos1[i][j]*(1<<(i*4+j));
    }
    return kk;
}
void fuc(int x){
    for(int i=0;i<4;i++){
        for(int j=0;j<4;j++)
            f[i][j]=(x>>(i*4+j))&1;
    }
}
void search(int x){
    queue<int>q;
    q.push(x);
    used[x]=1;
    dis[x]=0; 
    while(!q.empty()){
        int now=q.front();
        q.pop();
        if(now==b){
            ans=dis[now];
            return ;
        }
        fuc(now);
        for(int i=0;i<4;i++){
            for(int j=0;j<4;j++){
                if(f[i][j]==1){
                    for(int k=0;k<=3;k++){
                        int nowx=i+tx[k];
                        int nowy=j+ty[k];
                        if(nowx>=0&&nowy>=0&&nowx<=3&&nowy<=3&&f[nowx][nowy]==0){
                            f[nowx][nowy]=1;
                            f[i][j]=0;
                            int aa=dd(f); 
                            if(used[aa]==0){
                                used[aa]=1;
                                dis[aa]=dis[now]+1; 
                                q.push(aa);
                            }
                            f[nowx][nowy]=0;
                            f[i][j]=1;
                        }
                    }
                }
            }
        }
    }
}
int main(){
    for(int i=0;i<4;i++){
        string s;
        cin>>s;
        for(int j=0;j<s.size();j++){
            pos[i][j]=s[j]-'0';
            f[i][j]=pos[i][j];
        }
    }
    for(int i=0;i<4;i++){
        string s;
        cin>>s;
        for(int j=0;j<s.size();j++)
            a[i][j]=s[j]-'0';
    }
    b=dd(a);
    int fuc=dd(pos);
    search(fuc); 
    printf("%d\n",ans);
    return 0;
}

 

posted @ 2019-06-09 11:50  _Alex_Mercer  阅读(173)  评论(0编辑  收藏  举报