hdu5113 Black And White DFS+剪枝

点击打开链接

题意:

给你n*m的方格,你要用k种颜色去填,每种颜色要填ci次,并且要保证没有任意两个相邻的格子有相同的颜色,构造一种可行方法。

思路:

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

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 #define mem(a) memset(a,0,sizeof(a))
 5 #define mp(x,y) make_pair(x,y)
 6 const int INF = 0x3f3f3f3f;
 7 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
 8 inline ll read(){
 9     ll x=0,f=1;char ch=getchar();
10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
11     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
12     return x*f;
13 }
14 //////////////////////////////////////////////////////////////////////////
15 const int maxn = 1e5+10;
16 
17 int n,m,k,c[30];
18 int mp[10][10],flag;
19 int dx[4] = {0,0,1,-1};
20 int dy[4] = {1,-1,0,0};
21 
22 bool ok(int x,int y,int col){
23     for(int i=0; i<4; i++){
24         int tx=x+dx[i],ty=y+dy[i];
25         if(tx<0 || tx>=n || ty<0 || ty>=m) continue;
26         if(mp[tx][ty] == col) return false;
27     }
28     return true;
29 }
30 
31 void dfs(int sta){
32     if(flag) return ;
33     if(sta == n*m){
34         flag = true;
35         puts("YES");
36         for(int i=0; i<n; i++){
37             for(int j=0; j<m; j++){
38                 cout << mp[i][j];
39                 if(j==m-1) cout << endl;
40                 else cout << " ";
41             }
42         }
43         return ;
44     }
45 
46     int ma=-1;
47     for(int i=1; i<=k; i++) ma = max(ma,c[i]);
48     if(ma>(n*m-sta+1)/2) return ;
49 
50     int x=sta/m,y=sta%m;
51     for(int i=1; i<=k; i++){
52         if(c[i]==0) continue;
53         if(ok(x,y,i)){
54             mp[x][y] = i;
55             c[i]--;
56             dfs(sta+1);
57             mp[x][y] = -1;
58             c[i]++;
59         }
60     }
61 }
62 
63 int main(){
64     int T=read();
65     for(int cas=1; cas<=T; cas++){
66         memset(mp,-1,sizeof(mp));
67         flag = 0;
68         n=read(),m=read(),k=read();
69         for(int i=1; i<=k; i++)
70             c[i] = read();
71         cout << "Case #" << cas << ":\n";
72         dfs(0);
73         if(!flag) puts("NO");
74     }
75 
76     return 0;
77 }

 

posted @ 2017-02-23 21:38  _yxg123  阅读(94)  评论(0编辑  收藏  举报