题意:
给定n,m,k;代表n行m列的矩形,要求用k总颜色进行染色,要求任意两个相连的位置颜色不能相等,其中每种颜色有a【i】个;
思路:
暴力搜索加剪枝,首先记录数量最多的颜色有多少个,然后判断是否满足maxx>(n*m+1)>>1;如果满足,直接输出NO;
否则就是一定能染成的。
如何剪枝?当搜索过程中,如果ans代表剩下未染的方格,若a[i]>(ans+1)>>1,直接return就行了,这样下去肯定无法染成。
代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <string.h>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <list>
#include <bitset>
#include <stack>
#include <stdlib.h>
#define lowbit(x) (x&-x)
//ios::sync_with_stdio(false);
typedef long long ll;
typedef long long LL;
using namespace std;
int n,m,k;
int flag;
int s[6][6];
int ca;
int a[26];
void print()
{
cout<<"Case #"<<ca<<":"<<endl<<"YES"<<endl;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
if( j==m)
cout<<s[i][j]<<endl;
else
cout<<s[i][j]<<' ';
}
void dfs(int x,int y,int ans)
{
if(ans==0)
{
flag = -1;
return ;
}
for(int i=1;i<=k;i++)
{
if(a[i]>(ans+1)>>1)
return ;
}
for(int i=1; i<=k; i++)
if(flag==-1)
return;
else if(a[i])
{
if(s[x-1][y]!=i&&s[x][y-1]!=i)
{
a[i]--;
s[x][y]=i;
if(x==n&&y==m&&flag!=-1)
{
flag=-1;
print();
return;
}
if(y==m)
dfs(x+1,1,ans-1);
else
dfs(x,y+1,ans-1);
a[i]++;
}
}
}
int main()
{
int t;
cin>>t;
for(int ii=1; ii<=t; ++ii)
{
ca=ii;
cin >>n>>m>>k;
int maxx = 0;
for(int i=1; i<=k; ++i)
{
cin>>a[i];
maxx = max(maxx,a[i]);
}
if(maxx>(n*m+1)/2)
{
cout<<"Case #"<<ii<<":"<<endl<<"NO"<<endl;
continue;
}
flag=0;
dfs(1,1,n*m);
}
return 0;
}