本文根据http://www.cnblogs.com/fraud,这篇博客学习借鉴来的·····,知识产权很重要,我写博客的目的只是提升自己···做个笔记用···
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;
}