传送门:2014北京区域赛B题
给定一个n×m大小的棋盘,现在有k种颜色的涂料,每种颜色的涂料给一定的数量,要求给所有格子上色,要求任意两个格子之间不能同色,问能否做到,若能请输出任意一种上色方案。
坑了我好几天的题目,不想要用深搜,就想构造,结果各种跪跪跪,找不到一种能完全符合要求的构造方案,最后发现把多种构造混在一起就行了 sigh~~
将棋盘黑白染色
方案(一):将颜料按数量从大到小排序,然后先涂黑块再涂白块
方案(二):将颜料按数量从大到小排序,然后先涂白块再涂黑块
方案(三):先涂黑块再涂白块,上色顺序,把最大的涂掉,然后从小到大按颜料数量涂
/******************************************************
* File Name: b.cpp
* Author: kojimai
* Create Time: 2014年12月05日 星期五 13时24分16秒
******************************************************/
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
const int FFF = 30;
int n,m,k;
struct node
{
int num,col;
bool operator < (const node &a) const{
return num > a.num;
}
}p[FFF];
int col[7][7];
void solve1()
{
int now = 0,t = p[now].num;
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
if((i+j)%2==1)
{
col[i][j] = p[now].col;
if(!(--t))
{
now++;
t = p[now].num;
}
}
}
}
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
if((i+j)%2==0)
{
col[i][j] = p[now].col;
if(!(--t))
{
now++;
t = p[now].num;
}
}
}
}
}
void solve2()
{
int now = 0,t = p[now].num;
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
if((i+j)%2==0)
{
col[i][j] = p[now].col;
if(!(--t))
{
now++;
t = p[now].num;
}
}
}
}
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
if((i+j)%2==1)
{
col[i][j] = p[now].col;
if(!(--t))
{
now++;
t = p[now].num;
}
}
}
}
}
void solve3()
{
int now = 0,t = p[now].num;
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
if((i+j)%2 == 1)
{
col[i][j] = p[now].col;
t--;
if(!t)
{
if(now == 0)
now = k - 1;
else
now--;
t = p[now].num;
}
}
}
}
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
if((i+j)%2 == 0)
{
col[i][j] = p[now].col;
t--;
if(!t)
{
if(now == 0)
now = k - 1;
else
now--;
t = p[now].num;
}
}
}
}
}
bool judge()
{
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
if(i < n && col[i][j] == col[i+1][j]) return false;
if(j < m && col[i][j] == col[i][j+1]) return false;
}
}
return true;
}
void print()
{
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
if(j>1)
cout<<' ';
cout<<col[i][j];
}
cout<<endl;
}
}
int main()
{
int keng,Case = 1;
scanf("%d",&keng);
while(keng--)
{
scanf("%d%d%d",&n,&m,&k);
for(int i = 0;i < k;i++)
{
scanf("%d",&p[i].num);
p[i].col = i+1;
}
sort(p,p+k);
printf("Case #%d:\n",Case++);
if((n*m+1)/2 < p[0].num)
{
printf("NO\n");
continue;
}
solve1();
bool flag = judge();
if(!flag)
{
solve2();
flag = judge();
}
if(!flag)
{
solve3();
flag = judge();
}
/*if(!flag)
{
printf("Case #%d:\n",Case);
cout<<" num = "<<p[0].num<<endl;
print();
}*/
//solve3();
printf("YES\n");
print();
}
return 0;
}