hdu 5113 Black And White

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5113

题目分类:dfs

题意:N M K   N*M的棋盘  K种颜色  接下来K个数字分别代表每种颜色的数目  要求 相邻的格子的颜色不能相同,输出一种方案就好

题目分析:因为N和M的范围比较小,而且找到一种就好,所以,采用深度优先搜索即可

代码

#include<bits/stdc++.h>

using namespace std;

#define INF 0x3f3f3f3f

int N,M,K;
int number[30];
int a[10][10];
bool flag;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};

bool check(int i,int j,int val)
{
    for(int d=0;d<4;d++)
    {
        int tx=i+dx[d];
        int ty=j+dy[d];
        if(tx<=N&&ty<=M&&tx>=1&&ty>=1&&a[tx][ty]==val)
            return false;
    }
    return true;
}
/** 位置是i,j,,剩余的未被访问过的点有left个 */

void dfs(int i,int j,int left)  
{
    if (flag) return ;
    if (left==0)
    {
        flag=1;
        return ;
    }
    for (int d=1;d<=K;d++)
        if (number[d]>(left+1)/2) return ;

    if (j>M) dfs(i+1,1,left);
    else
    {
        for (int ii=1;ii<=K;ii++)
        {
            if (!check(i,j,ii)) continue;
            if (number[ii]==0) continue;
            number[ii]--;
            a[i][j]=ii;
            dfs(i,j+1,left-1);
            if (flag) return ;
            a[i][j]=0;
            number[ii]++;
        }
    }
}

int main()
{
    
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
    #endif
    
    int i,j,t;
    scanf("%d",&t);
    for(int kase=1;kase<=t;kase++)
    {
        scanf("%d%d%d",&N,&M,&K);
        for (i=1;i<=K;i++)
            scanf("%d",&number[i]);
            
        memset(a,0,sizeof(a));
        flag=0;
        dfs(1,1,N*M);
        printf("Case #%d:\n",kase);
        if(!flag)
            printf("NO\n");
        else
        {
            printf("YES\n");
            for(int i=1;i<=N;i++)
            {
                for(int j=1;j<=M;j++)
                {
                    if(j==1) printf("%d",a[i][j]);
                    else printf(" %d",a[i][j]);
                }
                printf("\n");
            }
        }
    }
    return 0;
}

 

posted @ 2015-11-10 20:40  Gssol  阅读(229)  评论(0编辑  收藏  举报