hdu 5113 Black And White(暴力+剪枝)

题目链接:hdu 5113 Black And White

题意:

给你n*m的格子,现在有k种颜色,每种颜色要填c[i]个格子,让你输出一种合法的填涂方案,相邻格子颜色不能相同。

题解:

暴搜+剪枝。

对于当前剩下的格子数,考虑剩下的c[i],如果剩下的c[i]>(剩下的格子数+1)/2,那么就不用往下搜了。

这样速度飞快,46msAC。

 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=(a);i<=(b);++i)
 3 using namespace std;
 4 
 5 int t,n,m,k,cas,a[30],flag,mp[10][10];
 6 
 7 int check(int have)
 8 {
 9     F(i,1,k)if(a[i]>(have+1)/2)return 1;
10     return 0;
11 }
12 
13 void dfs(int now,int have)
14 {
15     if(flag)return;
16     if(now>n*m)
17     {
18         int is=1;
19         F(i,1,k)if(a[i]){is=0;break;}
20         if(is)
21         {
22             puts("YES"),flag=1;
23             F(i,1,n)F(j,1,m)printf("%d%c",mp[i][j]," 
"[j==m]);
24             return;
25         }
26     }
27     if(check(have))return;
28     int x=(now-1)/m+1,y=(now-1)%m+1;
29     F(i,1,k)if(a[i])
30     {
31         if(mp[x-1][y]==i||mp[x][y-1]==i)continue;
32         mp[x][y]=i;
33         a[i]--;
34         dfs(now+1,have-1);
35         a[i]++;
36     }
37 }
38 
39 int main(){
40     scanf("%d",&t);
41     while(t--)
42     {
43         scanf("%d%d%d",&n,&m,&k);
44         F(i,1,k)scanf("%d",a+i);
45         printf("Case #%d:
",++cas);
46         flag=0,dfs(1,n*m);
47         if(!flag)puts("NO");
48     }
49     return 0;
50 }
View Code
原文地址:https://www.cnblogs.com/bin-gege/p/7622203.html