zoukankan      html  css  js  c++  java
  • HDU5113【DFS+剪枝】

    题意:
    n*m的矩阵
    k种颜色
    每种颜色有c[i]个
    上下左右相邻的格子不能一样的颜色
    问你有没有一种染色方法,有的话输出方案。
    思路:
    暴搜啊,n,m都才5,做完以后大哥的剪枝是奇偶剪枝,其实画完图我就应该想到了。然后自己想了好多,关于奇偶剪枝,自己也就做了HDU1010而已吧。
    然后自己的思路,一开始暴搜无剪枝T了,然后想到了最终两种颜色的时候一定是相等的,剩下的一半,然后还是T,这个剪枝还是不强,然后首先判一下每种颜色的数量是小于n*m/2的,那么就会想到每次的话就是都要小于n*m/2的;
    然后wa了。然后改啊改。。。最后发现每次dfs以后那个颜色数组会变。。没更新。。。= =、太久没写搜索了,真菜,还要搞搞奇偶剪枝;
    巨挫的code………

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N=1e4+10;
    int dx[4]={1,-1,0,0};
    int dy[4]={0,0,-1,1};
    int c[30];
    int ss[30];
    int ma[10][10];
    int vis[10][10];
    int flag;
    int n,m,num;
    
    bool judge(int x,int y,int temp)//判断这个点能不能放j颜色
    {
        for(int i=0;i<4;i++)
        {
            int xx=dx[i]+x;
            int yy=dy[i]+y;
            if(xx<1||yy<1||xx>n||yy>m)
                continue;
            if(vis[xx][yy])
                if(ma[xx][yy]==temp)
                    return false;
        }
        return true;
    }
    
    bool Judhe(int temp)//剪枝,小于剩下的二分之一
    {
        for(int j=2;j<=num;j++)
        {
            if(c[j]>temp/2)
                return false;
        }
        return true;
    }
    
    void dfs(int x,int y,int sum)//搜。。
    {
        if(flag)
            return;
        if(sum==n*m)
        {
            flag=1;
            return;
        }
        if(!Judhe(n*m-sum+1))
            return;
        for(int i=0;i<4;i++)
        {
            int xx=x+dx[i];
            int yy=y+dy[i];
            if(xx<1||yy<1||xx>n||yy>m||vis[xx][yy])
                continue;
            for(int j=1;j<=num;j++)
            {
                if(c[j])
                {
                    if(judge(xx,yy,j))
                    {
                        ma[xx][yy]=j;
                        vis[xx][yy]=1;
                        c[j]--;
                        dfs(xx,yy,sum+1);
                        if(flag)
                            return;
                        vis[xx][yy]=0;
                        c[j]++;
                    }
                }
            }
        }
    }
    //每次DFS以后,C[]数组改变!!!!一定要注意DFS后的后果,而且要注意必要的初始化处理。
    void init()
    {
        for(int j=1;j<=num;j++)
            c[j]=ss[j];
    }
    int main()
    {
        int T;
        int cas=1;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d%d",&n,&m,&num);
            for(int i=1;i<=num;i++)
            {
                scanf("%d",&ss[i]);
            }
            printf("Case #%d:
    ",cas++);
            int f1=0;
            init();
            for(int i=1;i<=num;i++)
            {
                if(c[i]>((n*m+1)/2))
                {
                    f1=1;
                    puts("NO");
                    break;
                }
            }
            if(f1)
                continue;
            flag=0;
            for(int i=1;i<=num;i++)
            {
                init();
                memset(vis,0,sizeof(vis));
                if(c[i])
                {
                    c[i]--;
                    vis[1][1]=1;
                    ma[1][1]=i;
                    dfs(1,1,1);
                }
    
    //                puts("");
    //            for(int j=1;j<=n;j++)
    //            {
    //                printf("%d ",c[j]);
    //            }
    //                puts("");
    
                if(flag)
                    break;
            }
            if(flag==1)
            {
                puts("YES");
                for(int i=1;i<=n;i++)
                {
                    for(int j=1;j<=m;j++)
                    {
                        if(j!=1)
                            printf(" ");
                        printf("%d",ma[i][j]);
                    }
                    puts("");
                }
            }
            else
                puts("NO");
        }
        return 0;
    }
  • 相关阅读:
    美团前端面经-2020-估计是凉了
    JavaScript的垃圾回收机制与内存泄漏
    从输入URL到浏览器显示页面发生了哪些事情---个人理解
    let 、const 、var、function声明关键字的新理解
    前端中堆和栈的概念
    今天想好好的认真开始维护自己的博客
    关于org.apache.poi 导出excel时引发的No such file or directory
    MySQL查询本周、上周、本月、上个月份数据的sql代码
    为mybatis mapper xml文件添加注释遇到问题
    ubuntu使用中遇到问题及解决方法持续整理
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/5934778.html
Copyright © 2011-2022 走看看