• 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 << ":
    ";
    72         dfs(0);
    73         if(!flag) puts("NO");
    74     }
    75 
    76     return 0;
    77 }
  • 相关阅读:
    Java基础总结--面向对象1
    Java基础总结--数组
    Java基础总结--方法(函数)
    Java基础总结--流程控制
    Java基础总结--变量、运算符总结
    Java基础总结--Java编程环境变量配置
    OpenWrt源码结构
    OpenWRT介绍
    内存管理
    makefie中的几种用法
  • 原文地址:https://www.cnblogs.com/yxg123123/p/6827699.html
Copyright © 2020-2023  润新知