本文根据http://www.cnblogs.com/fraud,这篇博客学习借鉴来的·····,知识产权很重要,我写博客的目的只是提升自己···做个笔记用···
Black And White
— 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.
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 .
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.
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
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
#include<iostream>
#include<cstdio>
#include<string.h>
#include<string>
#include<set>
#include<algorithm>
#include<cmath>
#define ll __int64
#define MAX 1000009
using namespace std;
int k;
int ans[109][109];
int a[109];
int n,m;
int flag;
void dfs(int x,int y,int xx)
{
if(!xx)//如果没有空位就会退回
{
flag = 1;
return ;
}
for(int i = 1;i<=k;i++)//如果剩下的个数大于空位数,退出(剪支)
{
if(a[i]>(xx+1)/2)
return ;
}
for(int i = 1;i<=k;i++)
{
if(!a[i])continue;//没有颜色跳过当前颜色循环
if(x&&ans[x-1][y]==i)continue;//如果周围有当前颜色就会跳过
if(y&&ans[x][y-1]==i)continue;//如果周围有当前颜色就会跳过
a[i]--;//用掉一个
ans[x][y] = i;//当前位置赋值成第i种颜色
if(y<m-1)
dfs(x,y+1,xx-1);//如果Y轴没有填满 先填Y轴
else
dfs(x+1,0,xx-1);//否则填X轴
if(flag) return ;
a[i]++;//不符合条件加回来
}
return ;
}
int main()
{
int cas = 1;
int t;
scanf("%d",&t);
while(t--)
{
//memset(ans,0,sizeof(ans));
flag = 0;
scanf("%d%d%d",&n,&m,&k);
for(int i = 1;i<=k;i++)scanf("%d",&a[i]);
printf("Case #%d:\n",cas++);
dfs(0,0,n*m);
if(flag)
{
printf("YES\n");
for(int i = 0;i<n;i++)
{
for(int j = 0;j<m;j++)
{
if(j)
printf(" ");
printf("%d",ans[i][j]);
}
printf("\n");
}
}
else
printf("NO\n");
}
return 0;
}