题意:告诉格子规格,颜色个数,以及每个颜色能涂得格子数目,问是否能够实现相邻两个格子的颜色数目不相同。
分析:因为数据很小,格子最多是5 * 5大小的,因此可以dfs。TLE了一次之后开始剪枝,31ms过。剪枝看代码。
1 #include <cstdio> 2 #include <iostream> 3 #include <sstream> 4 #include <cmath> 5 #include <cstring> 6 #include <cstdlib> 7 #include <string> 8 #include <vector> 9 #include <map> 10 #include <set> 11 #include <queue> 12 #include <stack> 13 #include <algorithm> 14 using namespace std; 15 #define ll long long 16 #define _cle(m, a) memset(m, a, sizeof(m)) 17 #define repu(i, a, b) for(int i = a; i < b; i++) 18 #define repd(i, a, b) for(int i = b; i >= a; i--) 19 #define sfi(n) scanf("%d", &n) 20 #define pfi(n) printf("%d\n", n) 21 #define MAXN 26 22 int n, m, k, tot; 23 int c[MAXN]; 24 int mpp[5][5], re[5][5]; 25 int tcc[MAXN]; 26 void put(int mp[][5]) 27 { 28 repu(i, 0, n) 29 { 30 repu(j, 0, m) 31 if(j == 0) 32 printf("%d", mp[i][j]); 33 else printf(" %d", mp[i][j]); 34 puts(""); 35 } 36 } 37 bool Judge(int tc[], int cur)///剪枝,剩下没染的颜色中的数目如果超过一半就break 38 { 39 repu(i, 0, k) if(c[i] - tc[i] > (tot - cur + 1) / 2) return true; 40 return false; 41 } 42 int debug(int cur,int mp[][5]) 43 { 44 cout<<cur<<endl; 45 put(mp); 46 } 47 bool dfs(int cur, int tc[], int mp[][5]) 48 { 49 ///当前已经染得格子数目,当前染得每个颜色剩下的数目,当前的已经订好的方案 50 ///debug(cur,mp); 51 if(cur >= n * m) return true; 52 int x = cur / m; 53 int y = cur - x * m; 54 if(Judge(tc, cur)) return false; 55 repu(i, 0, k) 56 { 57 if(tc[i] < c[i]) 58 { 59 if(x - 1 >= 0 && mp[x - 1][y] == i + 1) 60 continue; 61 if(y - 1 >= 0 && mp[x][y - 1] == i + 1) 62 continue; 63 tc[i]++; 64 mp[x][y] = i + 1; 65 if(dfs(cur + 1, tc, mp)) 66 return true; 67 tc[i]--; 68 } 69 } 70 return false; 71 } 72 int main() 73 { 74 int T; 75 sfi(T); 76 repu(kase, 1, T + 1) 77 { 78 sfi(n), sfi(m), sfi(k); 79 tot = n * m; 80 repu(i, 0, k) sfi(c[i]); 81 _cle(tcc, 0); 82 _cle(mpp, 0); 83 printf("Case #%d:\n", kase); 84 if(dfs(0, tcc, mpp)) 85 { 86 printf("YES\n"); 87 put(mpp); 88 } 89 else 90 printf("NO\n"); 91 } 92 return 0; 93 }
时间: 2024-10-12 08:18:42