题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5113
Problem Description In mathematics, the four color theorem, or the four color map theorem, states that, given any separation of a plane into contiguous regions, producing a figure called a map, no more than four colors are required to color the regions of the map so that no two adjacent regions have the same color.
Input The first line contains only one integer T (1 ≤ T ≤ 5000), which indicates the number of test cases.
Output For each test case, the first line contains “Case #x:”, where x is the case number (starting from 1). Sample Input
Sample Output
|
题目大意:给出一个n*m的矩阵,给出k种颜色,k种颜色共有n*m个(每个点都会被染色),染色要求是对于这个图,每个点的上下左右都不能颜色重复,但斜方向可以重复,我们分层依次染色,这样对于同一层的,只用判断它的左边和上边,对于下一层的,只用判断上边即可;
如果能染色到最后,那么则输出这个图(能够染色的所有的图种任意一个即可)
不难,注意剪枝:对于一个点来说,如果接下来要染色的点 小于某种颜色的数量的二倍,那么放弃这个方案(因为下面必定会同样的颜色相邻),剪去这部分,直接bfs即可:
ac:
//一页 27行就很舒服
#include<stdio.h>
#include<string.h>
#include<math.h>
//#include<map>
//#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
#define mod 998244353
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// 水印
//std::ios::sync_with_stdio(false);
int kind[30],map[10][10];
int n,m,k;
bool f;
void dfs(int x,int y,int color)
{
for(int i=1;i<=k;++i)//这种方案是否合理
{
if(kind[i]*2>((n-x)*m+m-y+1))
return ;
}
map[x][y]=color;
if(x==n&&y==m)
{
f=1;
return ;
}
if(y+1<=m)
{
int nx=x,ny=y+1;
for(int i=1;i<=k;++i)
{
if(kind[i]&&i!=map[nx][ny-1]&&i!=map[nx-1][ny])
{
kind[i]--;
dfs(nx,ny,i);//染色
if(f)
return ;
kind[i]++;
}
}
}
else if(x+1<=n)
{
int nx=x+1,ny=1;
for(int i=1;i<=k;++i)
{
if(kind[i]&&i!=map[nx-1][ny])
{
kind[i]--;
dfs(nx,ny,i);//染色
if(f)
return ;
kind[i]++;
}
}
}
}
int main()
{
std::ios::sync_with_stdio(false);
int t,cas=1;
cin>>t;
while(t--)
{
clean(kind,0);
clean(map,0);
f=0;
cin>>n>>m>>k;
for(int i=1;i<=k;++i)
cin>>kind[i];
for(int i=1;i<=k;++i)
{
kind[i]--;
dfs(1,1,i);
if(f)
break;
kind[i]++;
}
if(f)
{
cout<<"Case #"<<cas++<<":"<<endl<<"YES"<<endl;
for(int i=1;i<=n;++i)
{
for(int j=1;j<=m;++j)
{
if(j==m)
cout<<map[i][j]<<endl;
else
cout<<map[i][j]<<" ";
}
}
}
else
cout<<"Case #"<<cas++<<":"<<endl<<"NO"<<endl;
}
}