[hdu5113]Black And White2014北京赛区现场赛B题(搜索加剪枝)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud
Black And White
Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others)
Special Judge
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.
— 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 .
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.
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中颜色来进行填充,每种颜色可以使用的次数为ci次,∑ci=n*m,要求相邻的格子的颜色不能相同,问是否存在满足要求的染色方案,若存在,则输出其中一种。
分析:注意到n,m≤5,图较小,考虑用dfs来搞,但是光是dfs会T,所以需要加上一个剪枝。
若当前某种颜色的剩余数目大于剩余格子数目的一半,则必定不能完成填充方案,直接跳出。
1 //gaoshenbaoyou ------ pass system test 2 #include <iostream> 3 #include <sstream> 4 #include <ios> 5 #include <iomanip> 6 #include <functional> 7 #include <algorithm> 8 #include <vector> 9 #include <string> 10 #include <list> 11 #include <queue> 12 #include <deque> 13 #include <stack> 14 #include <set> 15 #include <map> 16 #include <cstdio> 17 #include <cstdlib> 18 #include <cmath> 19 #include <cstring> 20 #include <climits> 21 #include <cctype> 22 using namespace std; 23 #define XINF INT_MAX 24 #define INF 0x3FFFFFFF 25 #define MP(X,Y) make_pair(X,Y) 26 #define PB(X) push_back(X) 27 #define REP(X,N) for(int X=0;X<N;X++) 28 #define REP2(X,L,R) for(int X=L;X<=R;X++) 29 #define DEP(X,R,L) for(int X=R;X>=L;X--) 30 #define CLR(A,X) memset(A,X,sizeof(A)) 31 #define IT iterator 32 typedef long long ll; 33 typedef pair<int,int> PII; 34 typedef vector<PII> VII; 35 typedef vector<int> VI; 36 const int maxn=30; 37 int a[maxn]; 38 bool flag=0; 39 int ans[10][10]; 40 int n,m,k; 41 void dfs(int x,int y,int left) 42 { 43 if(!left) 44 { 45 flag=1; 46 return; 47 } 48 for(int i=1;i<=k;i++) 49 if(a[i]>(left+1)/2)return; 50 for(int i=1;i<=k;i++) 51 { 52 if(!a[i])continue; 53 if(x&&ans[x-1][y]==i)continue; 54 if(y&&ans[x][y-1]==i)continue; 55 a[i]--; 56 ans[x][y]=i; 57 if(y<m-1)dfs(x,y+1,left-1); 58 else dfs(x+1,0,left-1); 59 if(flag)return; 60 a[i]++; 61 } 62 return; 63 } 64 int main() 65 { 66 //ios::sync_with_stdio(false); 67 int t; 68 scanf("%d",&t); 69 int cas=1; 70 while(t--) 71 { 72 flag=0; 73 scanf("%d%d%d",&n,&m,&k); 74 int sum=0; 75 int maxx=0; 76 int tot=n*m; 77 for(int i=1;i<=k;i++) 78 scanf("%d",&a[i]); 79 printf("Case #%d:\n",cas++); 80 dfs(0,0,tot); 81 if(flag) 82 { 83 printf("YES\n"); 84 for(int i=0;i<n;i++) 85 { 86 for(int j=0;j<m;j++) 87 { 88 if(j)printf(" "); 89 printf("%d",ans[i][j]); 90 } 91 printf("\n"); 92 } 93 } 94 else 95 printf("NO\n"); 96 } 97 return 0; 98 }