hdu5113Black And White(深搜剪枝)
题目描述:
Black And White
Color an N × M chessboard with K colors numbered from 1 to K such that no two adjacent cells have the same color (two cells are adjacent if they share an edge). The i-th color should be used in exactly ci cells.
Matt hopes you can tell him a possible coloring.
Matt hopes you can tell him a possible coloring.
题目大意:给我们一个矩阵,再给出所有颜色的数目(总和等于矩阵大小),我们需要为所有空格涂上颜色,使得所有相邻空格颜色不相同,
思路:搜索与剪枝,先把所有颜色由大到小拍个序,即先选大的,可以更快找到可行解,这是一种优化思路,但是还是会超时,还有一个剪枝
就是判断(剩下的空格数+1)/2与是否能放下当前剩余个数最多的颜色,不能的话说明怎么放都放不好了,直接剪掉,顺利通关
AC代码:
#include<bits/stdc++.h> using namespace std; const int maxn = 50; int m, n, k; struct node { int num, id; bool operator<(node b) { return num < b.num; } }a[maxn]; int maze[maxn][maxn]; bool dfs(int x, int y,int last) { if (last == 0)return true; for (int i = 1; i <= k; i++) {//如果剩下的空格数目的1/2比任何一个颜色个数要小,就放不下了,剪枝 if ((last + 1) / 2 < a[i].num)return false; } for (int i = 1; i <= k; i++) { if (a[i].num == 0)continue; if (maze[x - 1][y] == a[i].id || maze[x][y - 1] == a[i].id)continue; a[i].num--; maze[x][y] = a[i].id; int tx = x, ty = y + 1; if (ty > n) { tx++; ty = 1; } if (dfs(tx, ty, last - 1))return true; a[i].num++; maze[x][y] = 0; } return false; } int main() { //freopen("test.txt", "r", stdin); int t; scanf("%d", &t); for (int cse = 1; cse <= t;cse++) { memset(maze, 0, sizeof(maze)); scanf("%d%d%d", &m, &n, &k); for (int i = 1; i <= k; i++) { scanf("%d", &a[i].num); a[i].id = i; } sort(a + 1, a + k + 1); printf("Case #%d:\n", cse); if (dfs(1, 1, n * m)) { printf("YES\n"); for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { printf("%d", maze[i][j]); if (j != n)printf(" "); else printf("\n"); } } } else { printf("NO\n"); } } return 0; }

浙公网安备 33010602011771号