HDU 5113 Black And White ( 2014 北京區預賽 B 、搜索 + 剪枝 )
阿新 • • 發佈:2018-10-02
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]; intView Codenum[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; }
HDU 5113 Black And White ( 2014 北京區預賽 B 、搜索 + 剪枝 )