1. 程式人生 > >HDU 5113 Black And White ( 2014 北京區預賽 B 、搜索 + 剪枝 )

HDU 5113 Black And White ( 2014 北京區預賽 B 、搜索 + 剪枝 )

str num 很好 con ack memset -- display 分析

題目鏈接

題意 : 給出 n * m 的網格、要你用 k 種不同的顏色填給出的網格、使得相鄰的格子顏色不同、若有解要輸出具體的方案

分析 :

看似構造、實則搜索、手構構半天沒有什麽好想法

直接搜就行了、註意加上剪枝

當剩下格子不足以讓剩下顏色數量最多的顏色產生間隔的話則返回

具體也很好實現、即 max( 剩下的最多數量的那種顏色的數量 ) > ( 還剩多少格子 + 1 ) / 2

技術分享圖片
#include<bits/stdc++.h>
using namespace std;

const int maxn = (int)1e2 + 10;

int rem[maxn];
int
num[maxn]; int G[maxn][maxn]; int n, m, k; int len; bool Check(int tot) { for(int i=1; i<=k; i++) if(rem[i] > (tot+1)/2) return false; return true; } bool DFS(int r, int c, int cur) { if(cur == 0) return true; if(!Check(cur)) return false; for(int i=1; i<=k; i++){
if(rem[i] > 0 && G[r][c-1] != i && G[r-1][c] != i){ rem[i]--; G[r][c] = i; int rr, cc; if(c + 1 > m) rr = r+1, cc = 1; else rr = r, cc = c + 1; if(DFS(rr, cc, cur-1)) return true; G[r][c] = 0; rem[i]
++; } }return false; } int main(void) { int nCase; scanf("%d", &nCase); for(int T=1; T<=nCase; T++){ memset(G, 0, sizeof(G)); scanf("%d %d %d", &n, &m, &k); len = n * m; for(int i=1; i<=k; i++){ scanf("%d", &num[i]); rem[i] = num[i]; } printf("Case #%d:\n", T); if(DFS(1, 1, len)){ puts("YES"); int idx = 1; for(int i=1; i<=n; i++){ for(int j=1; j<=m; j++){ if(j == 1) printf("%d", G[i][j]); else printf(" %d", G[i][j]); }puts(""); } }else puts("NO"); } return 0; }
View Code

HDU 5113 Black And White ( 2014 北京區預賽 B 、搜索 + 剪枝 )