[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.

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中颜色来进行填充,每种颜色可以使用的次数为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 }

代码君

时间: 2024-10-09 18:31:32

[hdu5113]Black And White2014北京赛区现场赛B题(搜索加剪枝)的相关文章

HDU 5120 Intersection(2014北京赛区现场赛I题 计算几何)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5120 解题报告:给你两个完全相同的圆环,要你求这两个圆环相交的部分面积是多少? 题意看了好久没懂.圆环由一个大圆里面套一个小圆,中间部分就是圆环,两圆环相交面积 = 大圆相交的面积 - 2*大圆与小圆相交的面积 + 小圆与小圆相交的面积. 也就是说,这题就可以化为求两个圆的相交的面积了.可以利用两个圆的方程,求出圆的交点所在的直线,然后求出圆心到这条直线的距离,就可以求出两个圆对应的扇形的圆心角是多

HDU 5120 A Curious Matt(2014北京赛区现场赛A题 简单模拟)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5112 解题报告:扫一遍 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 const int maxn = 1e6+5; 8 9 struct node

HDU 4119 Isabella&#39;s Message (2011年成都赛区现场赛I题)

1.题目描述:点击打开链接 2.解题思路:本题是一道模拟题,要求模拟一个解密的过程,练习这么久第一次做模拟题1Y了,内心还是很激动的~.只需要根据题意,记录* 所在的位置即可,然后每次都是先解密,后顺时针旋转90度.把每次解密的信息放到一个vector里,接下来就是连接它们,得到解密后的字符串,在map中查找这些单词是否存在即可.如果都存在,就把这条解密信息放到ans中,最后对ans排序,输出ans[0]就是答案. 3.代码: //#pragma comment(linker, "/STACK:

ACM总结——2017ACM-ICPC北京赛区现场赛总结

现在距离比赛结束已经过了一个多星期了,也是终于有时间写下心得了.回来就是被压着做项目,也是够够的. 这次比赛一样是我和两个学弟(虽然是学弟,但我的实力才是最弱的T_T)一起参加的,成绩的话打铁,算是情理之中意料之外了,我们本来以为自己会在北京赛区拿个倒数20什么的(比赛前听说北京赛区是最难的),事实上虽然不是很简单,但是也绝对没有想象中难(以为会A1或者零来着). 说下比赛前吧~赛前一星期是软考,所有自己训练很少,也正是这样,这场比赛算是抱了大腿(自己太菜了..)!咳咳~虽然软考复习了两周,但是

HDU 4435 charge-station (2012年天津赛区现场赛E题)

1.题目描述:点击打开链接 2.解题思路:本题利用DFS解决.不过本题的解法颇为巧妙,注意到2^0+2^1+...+2^(i-1)<2^i,这就意味着即使在0~i-1都建立加油站,费用也会小于单独在i处建立加油站.这就提示我们,可以一开始全部都建立加油站,然后从大到小依次尝试着删除加油站,如果可以删除,就删除,如果不可以,再添加上.那么该如何判断删除第i处之后是否可行呢?可以利用dfs判断,如果当前访问结点u是建立过加油站的,如果它的邻接点v也是建立了加油站的,且dist(u,v)<=d,那么

hdu 4431 第37届ACM/ICPC 天津赛区现场赛A题 枚举

题意:就是给了13张牌.问增加哪些牌可以胡牌.m是数字,s是条,p是筒,c是数字 胡牌有以下几种情况: 1.一个对子 +  4组 3个相同的牌或者顺子.  只有m.s.p是可以构成顺子的.东西南北这样的牌没有顺子. 2.7个不同的对子. 3.1m,9m,1p,9p,1s,9s,1c,2c,3c,4c,5c,6c,7c.  这13种牌每种都有,而且仅有这13种牌.肯定是有一种2张.其他的1张. 模拟即可,第一个对子的情况需要枚举 很麻烦的模拟,但是貌似稳银的很需要这题,所以这种难度必须要弄懂,加油

ZOJ3822 ACM-ICPC 2014 亚洲区域赛牡丹江赛区现场赛D题Domination 概率DP(两种解法)

题目地址:点击打开链接 这道题有两种做法,第一种是直接求期望,类似于poj 2096 区别在于这个步数有限.所以要迭代步数. #include <cstdio> #include <cstring> #include <iostream> #define maxn 55//这里刚开始写成了50+10 那么maxn*maxn就会小很多wa了一次 using namespace std; double dp[maxn][maxn][maxn*maxn]; int N,M,T

HDU 5128 The E-pang Palace(2014广州赛区现场赛B题 计算几何)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5128 解题报告:在一个平面上给出n个点的坐标,用这n个点作为矩形的四个顶点,作两个矩形,要求两个矩形不能相交,也不能有边和点相交,然后两个矩形的面积之和要最大,求最大的面积之和是多少?如果不存在输出imp 因为n <=30,所以可以先把所有的矩形枚举出来,然后再暴力判断两两矩形组合,首先要满足位置关系,然后取面积和最大就是了.要注意的地方就是要小心一个大矩形包含一个小矩形的情况,在这种情况下,是满足

HDU 4422 The Little Girl who Picks Mushrooms (2012年成都赛区现场赛C题)

1.题目描述:点击打开链接 2.解题思路:本题是一道简单模拟题,然而,自己的方法不对WA了很多次==.最后不得不弃用自己的思路了.首先用-1表示还没有使用过的位置.可以每次枚举3个位置,如果发现这3个位置中没有-1且他们的和不能被1024整除,那么return 0,否则,找到没有被标记的另外2个位置,如果这2个位置其中一个为-1,那么直接返回1024,因为我们已经交了三个袋子了,剩下的袋子中如果又没有确定的,那么一定可以凑成1024.否则,计算这2个位置的和,然后看减去若干次1024后剩下多少,