题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5113
#include<bits/stdc++.h>
using namespace std;
#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
#define ll long long
#define lrt int l,int r,int rt
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define root l,r,rt
#define mst(a,b) memset((a),(b),sizeof(a))
#define pii pair<int,int>
#define fi first
#define se second
#define mk(x,y) make_pair(x,y)
const int mod=1e9+7;
const int maxn=1e5+4;
const int ub=1e6;
ll powmod(ll x,ll y){ll t; for(t=1;y;y>>=1,x=x*x%mod) if(y&1) t=t*x%mod; return t;}
ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
/*
题目大意:给定k种颜色和其颜色的个数,
和一个二维平面,问是否存在一种涂色方案,
使得相邻两个颜色不同,k种颜色总数和二维平面格数一样。
题目分析:由于范围很小,直接暴力搜索即可,
我这次的搜索自我感觉思维是超级精简了呢~QAQ
但是还是少了个剪枝操作T_T。。。被wa了。
首先是搜索的逻辑,我们只要安排当前维护好的二维平面中,
当前点左方和上方不冲突的颜色即可,其正确性感觉和dp思维比较像。
然后就是剪枝。。。get到一个点就是:剩余格数/2如果小于某个颜色数,
那么必然对于这个颜色来说会有相邻的相同,这样的剪枝逻辑,
大体就是考虑了极端情况吧,充分利用相邻性。'
时间复杂度:O(x^25*T+剪枝),,能过。。
*/
int n,m,k,flag;
int a[30],b[6][6];
void dfs(int pos){///考虑剪枝
if(flag) return ;
if(pos==n*m){flag=1;return ;}
rep(i,0,k) if( (n*m-pos+1)/2 < a[i] ) return ;///剪枝
int tn=pos/m,tm=pos%m;
rep(i,0,k) if(a[i]){
if(flag) return ;
if(tn-1>=0&&b[tn-1][tm]==i+1) continue;
if(tm-1>=0&&b[tn][tm-1]==i+1) continue;
a[i]--,b[tn][tm]=i+1;
dfs(pos+1);
a[i]++;
}
}
int main(){
int t;scanf("%d",&t);
for(int ca=1;ca<=t;ca++){
scanf("%d%d%d",&n,&m,&k);
rep(i,0,k) scanf("%d",&a[i]);
printf("Case #%d:\n",ca);
flag=0,dfs(0);///搜索
if(!flag) puts("NO");
else{
puts("YES");
rep(i,0,n) rep(j,0,m) printf("%d%c",b[i][j],j==m-1?'\n':' ');
}
}
return 0;
}