HDU-5113-Black And White(dfs+剪枝)

题目链接: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.
— Wikipedia, the free encyclopedia

In this problem, you have to solve the 4-color problem. Hey, I’m just joking.

You are asked to solve a similar problem:

Color an N × M chessboard with K colors numbered from 1 to K such that no two adjacent cells have the same color (two cells are adjacent if they share an edge). The i-th color should be used in exactly ci cells.

Matt hopes you can tell him a possible coloring.

 

Input

The first line contains only one integer T (1 ≤ T ≤ 5000), which indicates the number of test cases.

For each test case, the first line contains three integers: N, M, K (0 < N, M ≤ 5, 0 < K ≤ N × M ).

The second line contains K integers ci (ci > 0), denoting the number of cells where the i-th color should be used.

It’s guaranteed that c1 + c2 + · · · + cK = N × M .

 

Output

For each test case, the first line contains “Case #x:”, where x is the case number (starting from 1).

In the second line, output “NO” if there is no coloring satisfying the requirements. Otherwise, output “YES” in one line. Each of the following N lines contains M numbers seperated by single whitespace, denoting the color of the cells.

If there are multiple solutions, output any of them.

Sample Input


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

Sample Output


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

题目大意:给出一个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;
	}
}

猜你喜欢

转载自blog.csdn.net/qq_40482358/article/details/81671141