题目;http://acm.hdu.edu.cn/showproblem.php?pid=5113
参考自:http://blog.youkuaiyun.com/howardemily/article/details/53022562
跟四色定理没什么关系,可以用好多种颜色,但有使用次数限制。
有一个包含从1到K一共K种颜色的N×M棋盘,使得任意两个相邻的区块不能有相同的颜色
(如果它们的上、下、左、右任意一边的颜色与自身颜色不同)。第i种颜色可以被使用Ci次。
哎呀,写的太差了,根本不会写,不知道不行的话回溯回来直接能改回来。
#include<bits\stdc++.h>
using namespace std;
int mp[10][10],k,n,m,flag,color[30];
void dfs(int x,int y,int sum){
if(sum==0){
flag=1;
return ;
}
for(int i=1;i<=k;i++) //枝剪,某数剩下的大于一半一定不行
if((sum+1)/2<color[i])
return ;
for(int i=1;i<=k;i++){
if(color[i]){
if(mp[x][y-1]!=i&&mp[x-1][y]!=i){ //只与上面和左面的比较即可
color[i]--;
mp[x][y]=i;
if(y==m)
dfs(x+1,1,sum-1); //y要从1开始
else
dfs(x,y+1,sum-1);
if(flag)
return;
color[i]++; //不对就回溯的时候改回来
mp[x][y]=0;
}
}
}
return;
}
int main(){
int t,ans=1;
scanf("%d",&t);
while(t--){
flag=0;
memset(color,0,sizeof(color));
memset(mp,0,sizeof(mp));
cin>>n>>m>>k;
for(int i=1;i<=k;i++)
cin>>color[i];
dfs(1,1,n*m);
printf("Case #%d:\n",ans++);
if(flag==0)
printf("NO\n");
else{
printf("YES\n");
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
printf("%d",mp[i][j]);
if(j!=m)
printf(" ");
}
printf("\n");
}
}
}
return 0;
}