【DFS+剪枝】HDU - 5113 B - Black And White

B - Black And White  HDU - 5113

In mathematics, the four color theorem, or the four color map theorem, states that, given any separation of a plane into contiguous regions, producing a figure called a map, no more than four colors are required to color the regions of the map so that no two adjacent regions have the same color. 
— Wikipedia, the free encyclopedia 

In this problem, you have to solve the 4-color problem. Hey, I’m just joking. 

You are asked to solve a similar problem: 

Color an N × M chessboard with K colors numbered from 1 to K such that no two adjacent cells have the same color (two cells are adjacent if they share an edge). The i-th color should be used in exactly c i cells. 

Matt hopes you can tell him a possible coloring.

Input

The first line contains only one integer T (1 ≤ T ≤ 5000), which indicates the number of test cases. 

For each test case, the first line contains three integers: N, M, K (0 < N, M ≤ 5, 0 < K ≤ N × M ). 

The second line contains K integers c i (c i > 0), denoting the number of cells where the i-th color should be used. 

It’s guaranteed that c 1 + c 2 + · · · + c K = N × M . 

Output

For each test case, the first line contains “Case #x:”, where x is the case number (starting from 1). 

In the second line, output “NO” if there is no coloring satisfying the requirements. Otherwise, output “YES” in one line. Each of the following N lines contains M numbers seperated by single whitespace, denoting the color of the cells. 

If there are multiple solutions, output any of them.

Sample Input

4
1 5 2
4 1
3 3 4
1 2 2 4
2 3 3
2 2 2
3 2 3
2 2 2

Sample Output

Case #1:
NO
Case #2:
YES
4 3 4
2 1 2
4 3 4
Case #3:
YES
1 2 3
2 3 1
Case #4:
YES
1 2
2 3
3 1

题目大意:给出一个n*m的矩阵,给出k种颜色,k种颜色共有n*m个(每个点都会被染色),染色要求是对于这个图,每个点的上下左右都不能颜色重复,但斜方向可以重复,我们分层依次染色,这样对于同一层的,只用判断它的左边和上边,对于下一层的,只用判断上边即可;

如果能染色到最后,那么则输出这个图(能够染色的所有的图种任意一个即可)

不难,注意剪枝:对于一个点来说,如果接下来要染色的点 小于某种颜色的数量的二倍,那么放弃这个方案(因为下面必定会同样的颜色相邻),剪去这部分,直接dfs即可:

#include <bits/stdc++.h>
using namespace std;
int ans[10][10],col[30];
int n,m,k,flag;
void dfs(int x,int y,int color)
{
    for(int i=1;i<=k;i++)
    {
        if(col[i]*2>(n-x)*m+m-y+1)
        {
            flag=0;
            return ;
        }
    }
    ans[x][y]=color;
    if(x==n&&y==m)
    {
        flag=1;
        return;
    }

    if(y+1<=m)
    {
        int nx=x,ny=y+1;
        for(int i=1;i<=k;i++)
        {
            if(col[i]&&ans[nx][ny-1]!=i&&ans[nx-1][ny]!=i)
            {
                col[i]--;
                dfs(nx,ny,i);
                if(flag) return;
                col[i]++;
            }
        }
    }
    else if(x+1<=n)
    {
        int nx=x+1,ny=1;
        for(int i=1;i<=k;i++)
        {
            if(col[i]&&ans[nx-1][ny]!=i)
            {
                col[i]--;
                dfs(nx,ny,i);
                if(flag) return;
                col[i]++;
            }
        }
    }
}


int main()
{
    int T,cas=0;
    scanf("%d",&T);
    while(T--)
    {
        memset(ans,0,sizeof(ans));
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=k;i++)
            scanf("%d",&col[i]);
        flag=0;
        for(int i=1;i<=k;i++)
        {
            col[i]--;
            dfs(1,1,i);
            if(flag) break;
            col[i]++;
        }
        printf("Case #%d:\n",++cas);
        if(flag)
        {
            printf("YES\n");
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                {
                    if(j==1) printf("%d",ans[i][j]);
                    else printf(" %d",ans[i][j]);
                }
                printf("\n");
            }
        }
        else printf("NO\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41037114/article/details/82792454