1 条题解

  • 0
    @ 2025-7-2 15:09:14
    #include<bits/stdc++.h>
    using namespace std;
    int n,dep=0;
    int v[10][10],a[10][10]; 
    int vis[10];
    int dx[4]={1,-1,0,0};//x坐标偏移量。 
    int dy[4]={0,0,1,-1};//y坐标偏移量。 
    int get(){//估价函数+判断整张图是否为同一颜色。 
        memset(vis,0,sizeof(vis));
        int ans=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(v[i][j]!=1){
                    vis[a[i][j]]=1;//把出现的标记上。 
                } 
            }
        }
        for(int i=0;i<6;i++){
            if(vis[i]==1){
                ans++;//统计还有几种颜色。 
            }
        }
        return ans;
    } 
    void p(int x,int y,int s){
        v[x][y]=1;
        for(int i=0;i<4;i++){
            int o1=x+dx[i],o2=y+dy[i];
            if(o1<=0||o2<=0||o1>n||o2>n||v[o1][o2]==1){//出界或已访问过。 
                continue;
            }
            if(a[o1][o2]!=s){//和要涂的颜色不一样,但可能接下来会被拓展,所以打标记。 
                v[o1][o2]=2;
                continue;
            }
            p(o1,o2,s);//涂下一个方块。 
        }
    }
    bool dfs(int de){
        int gj=get();
        if(gj==0){//只有一种颜色了,成功。 
            return true;
        }
        if(de+gj>dep){//超过能走的步数,返回。 
            return false;
        }
        int bf[10][10];//备份v数组。 
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                bf[i][j]=v[i][j];
            }
        }
        for(int i=0;i<6;i++){
            int f=0;//判断是否能拓展。 
            for(int j=1;j<=n;j++){
                for(int k=1;k<=n;k++){
                    if(v[j][k]==2&&a[j][k]==i){//在当前颜色与我们要涂的颜色相同时拓展。 
                        p(j,k,i);
                        f=1;
                    }
                }
            }
            if(f==1&&dfs(de+1)){//如果能拓展就尝试。 
                return true;//dfs成功,一路返回到底。 
            }
            for(int i=1;i<=n;i++){//把v数组复原。 
                for(int j=1;j<=n;j++){
                    v[i][j]=bf[i][j];
                }
            }
        }
        return false;
    }
    int main(){
        while(1){//多组数据。 
            cin>>n;
            if(n==0){
                break;
            }
            memset(v,0,sizeof(v));//初始化。 
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    cin>>a[i][j];
                }
            }
            p(1,1,a[1][1]);//先把左上角涂一次。 
            dep=0;
            while(1){//迭代加深。 
                if(dfs(0)){//当dfs成功时输出步数。 
                    cout<<dep<<"\n";
                    break;
                }
                dep++;
            }
        }
        return 0;
    }
    
    • 1

    信息

    ID
    128
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者