HDU 5113 Black And White 回溯+剪枝

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5113

Black And White

Time Limit: 2000/2000 MS (Java/Others)Memory Limit: 512000/512000 K (Java/Others)
#### 问题描述
> 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.

输入

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 .

输出

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.

样例输入

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

样例输出

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种颜色去填,每种颜色要填ci次,并且要保证没有任意两个相邻的格子有相同的颜色,构造一种可行方法,如果不存在输出-1.

题解

直接暴力回溯+剪枝,当没填的颜色中同种颜色数量超过(剩余格子+1)/2的时候,不可能合法。

代码

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf typedef int LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII; const int INF=0x3f3f3f3f;
const LL INFL=10000000000000000LL;
const double eps=1e-9; const double PI = acos(-1.0); //start---------------------------------------------------------------------- const int maxn=33; int n,m,k;
int arr[maxn];
int mat[7][7];
bool su;
const int dx[]={-1,1,0,0};
const int dy[]={0,0,-1,1}; bool ok(int x,int y,int color){
for(int i=0;i<4;i++){
int nx=x+dx[i];
int ny=y+dy[i];
if(nx<0||nx>=n||ny<0||ny>=m) continue;
if(mat[nx][ny]==color) return false;
}
return true;
} void dfs(int sta){
if(sta==n*m){
su=true;
prf("YES\n");
rep(i,0,n){
rep(j,0,m){
prf("%d",mat[i][j]);
if(j==m-1) prf("\n");
else prf(" ");
}
}
return;
} ///剪枝
int ma=0;
for(int i=1;i<=k;i++) ma=max(ma,arr[i]);
if(ma>(n*m-sta+1)/2) return; ///回溯
int x=sta/m,y=sta%m;
for(int i=1;i<=k;i++){
if(arr[i]==0) continue;
if(ok(x,y,i)){
mat[x][y]=i;
arr[i]--;
dfs(sta+1);
if(su) return;
arr[i]++;
mat[x][y]=-1;
}
}
} void init(){
clr(mat,-1);
} int main() {
int tc,kase=0;
scf("%d",&tc);
while(tc--) {
init();
scf("%d%d%d",&n,&m,&k);
for(int i=1;i<=k;i++){
scf("%d",&arr[i]);
}
prf("Case #%d:\n",++kase);
su=false;
dfs(0);
if(!su) prf("NO\n");
}
return 0;
} //end-----------------------------------------------------------------------
上一篇:Charles问题


下一篇:tyvj100题留念