zoukankan      html  css  js  c++  java
  • ID(dfs+bfs)-hdu-4127-Flood-it!

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=4127

    题目意思:

    给n*n的方格,每个格子有一种颜色(0~5),每次可以选择一种颜色,使得和左上角相连(颜色相同以及相邻,间接也行)的所有的格子都为该颜色。求最少的步数,使得所有的方格颜色都相同。

    解题思路:

    bfs+bfs死活不给过。

    正确解法应该是ID(dfs+bfs).因为总共的解的步数不多。

    减枝:

    1、当剩余的颜色种数(至少还要这么多步)+已走的步数>设定深度时 跳出。

    2、注意每次搜的时候保证比前面的方格数多。

    PS:时间卡的紧,不用STL,用手写队列。

    代码:

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<stack>
    #include<list>
    #include<queue>
    #include<ctime>
    #define eps 1e-6
    #define INF 0x3f3f3f3f
    #define PI acos(-1.0)
    #define ll __int64
    #define lson l,m,(rt<<1)
    #define rson m+1,r,(rt<<1)|1
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    using namespace std;
    
    #define Maxn 10
    int sa[Maxn][Maxn],n,ans,dep;
    int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
    bool flag;
    
    struct Po
    {
        int x,y;
    }q[80];
    
    struct Inf
    {
        int cnt;
        Po pp[70];
    }; //存储一个连通块内的所有节点
    bool vis[Maxn][Maxn];
    bool iscan(int x,int y) //判断是否越界
    {
        if(x<=0||x>n||y<=0||y>n)
            return false;
        return true;
    }
    void bfs(Inf & s,int co[])
    {
        memset(vis,false,sizeof(vis));
        //queue<Inf>myq;
        s.cnt=0;
        Po tmp;
        tmp.x=1,tmp.y=1;
        s.pp[++s.cnt]=tmp;
        vis[1][1]=true;
        //myq.push(s);
        int head=0,tail=-1;
        q[++tail]=tmp;
    
        while(head<=tail)
        {
            //Inf cur=myq.front();
            //myq.pop();
            Po cur=q[head];
            ++head;
    
            int xx=cur.x,yy=cur.y;
            for(int i=0;i<4;i++)
            {
                int x=xx+dir[i][0],y=yy+dir[i][1];
                if(!iscan(x,y)||vis[x][y]||sa[x][y]!=sa[xx][yy])
                    continue;
                vis[x][y]=true;
                Po tt;
                tt.x=x,tt.y=y;
                s.pp[++s.cnt]=tt;
                //myq.push(s);
                q[++tail]=tt;
            }
        }
        for(int i=1;i<=n;i++) //统计还没有进入连通块内的颜色种数
            for(int j=1;j<=n;j++)
            {
                if(!vis[i][j])
                    co[sa[i][j]]++;
            }
    
    }
    void dfs(int co,int step,int num) //当前颜色,已走步数,已联通的方格个数
    {
        if(step>dep||flag)
            return ;
        int cc[6]={0};
        Inf tmp;
        bfs(tmp,cc);
        if(tmp.cnt<=num)//往多的方格搜,不然浪费步数
            return ;
        num=tmp.cnt;
        //printf(":%d
    ",num);
        //system("pause");
        if(num==n*n) //找到了
        {
            flag=true;
            ans=step;
            return ;
        }
        int nn=0;
        for(int i=0;i<6;i++)
            if(cc[i])
                nn++;
        if(nn+step>dep) //至少要这么多步
            return ;
        for(int i=0;i<6;i++)
        {
            if(i==co)
                continue;
            for(int j=1;j<=tmp.cnt;j++)
                sa[tmp.pp[j].x][tmp.pp[j].y]=i;
            dfs(i,step+1,num);
            for(int j=1;j<=tmp.cnt;j++) //回溯
                sa[tmp.pp[j].x][tmp.pp[j].y]=co;
        }
    
    
    }
    void IDA()
    {
        flag=false;
        dep=1;
        while(!flag) //迭代加深搜索
        {
            dfs(sa[1][1],0,0);
            ++dep;
        }
    }
    
    int main()
    {
        while(scanf("%d",&n)&&n)
        {
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    scanf("%d",&sa[i][j]);
            IDA();
            printf("%d
    ",ans);
        }
       return 0;
    }
    




  • 相关阅读:
    第01组 Alpha冲刺(2/6)
    第01组 Alpha冲刺(1/6)
    第08组 Alpha冲刺(6/6)
    2019 SDN上机第4次作业
    第08组 Alpha冲刺(5/6)
    2019 SDN阅读作业
    2019 SDN上机第3次作业
    第08组 Alpha冲刺(4/6)
    第08组 Alpha冲刺(3/6)
    第08组 Alpha冲刺(2/6)
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3339423.html
Copyright © 2011-2022 走看看