Hdu OJ 5113 Black And White (2014ACM/ICPC亚洲区北京站) (搜索)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5113
题目大意:有k种颜色的方块,每种颜色有ai个, 现在有n*m的矩阵, 问这k种颜色的方块能否使任意两个相连的方块颜色不一样填满整个矩阵,如果可以输出任意一种。
解题思路:由于n,m在[1, 5]内, 所以直接暴力枚举; 需要注意的是:需要剪枝一下。
代码如下:
#include<stdio.h> #include<string.h> #include<cmath> #include<queue> #include<algorithm> using namespace std; typedef long long ll; const int N = 103; int n, m, k; int a[N], mp[N][N]; bool is; bool judge(int x, int y, int s) { bool p = true, q = true; if(x - 1 >= 1 && mp[x-1][y] == s) p = false; if(y - 1 >= 1 && mp[x][y-1] == s) q = false; return p && q; } void dfs(int x, int y, int cou) { int sum = 0, mx = 0; for(int i=1; i<=k; ++ i) { sum += a[i]; if(a[i] > mx) mx = a[i]; } if(sum - mx < mx - 1) return; if(cou == n*m) { is = true; return ; } for(int i=1; i<=k; ++ i) { if(a[i] && judge(x, y, i)) { a[i] --; mp[x][y] = i; if(y == m) dfs(x+1, 1, cou + 1); else dfs(x, y+1, cou + 1); if(is) return ; a[i] ++; } } } void solve(int cases) { scanf("%d%d%d", &n, &m, &k); int sum = 0, mx = 0; for(int i=1; i<=k; ++ i) { scanf("%d", &a[i]); sum += a[i]; if(a[i] > mx) mx = a[i]; } printf("Case #%d:\n", cases); if(sum - mx < mx - 1) printf("NO\n"); else { printf("YES\n"); memset(mp, -1, sizeof(mp)); is = false; dfs(1, 1, 0); for(int i=1; i<=n; ++ i) for(int j=1; j<=m; ++ j) printf(j == m? "%d\n" : "%d ", mp[i][j]); } } int main() { int t; scanf("%d", &t); for(int i = 1; i <= t; ++ i) { solve(i); } return 0; }