题意:给定一个n * n(1 <= n <= 10)的网格,有些已经填上了一些大写字母,需要补充完所有的字母,使每两两相邻的格子中的字母不同,且从上至下,从左至右,组成一个字符串后字典序最小。
由于组成字符串后的长度都为n * n,故字典序越往前的字母决定的优先级越大,所以贪心即可,从上到下,从左到右的补充格子里的字母,尽可能的使当前可以补充的字母尽量小。
#include<cstdio> #include<cstring> #include<cctype> #include<cstdlib> #include<cmath> #include<iostream> #include<sstream> #include<iterator> #include<algorithm> #include<string> #include<vector> #include<set> #include<map> #include<deque> #include<queue> #include<stack> #include<list> #define fin freopen("in.txt", "r", stdin) #define fout freopen("out.txt", "w", stdout) #define pr(x) cout << #x << " : " << x << " " #define prln(x) cout << #x << " : " << x << endl typedef long long ll; typedef unsigned long long llu; const int INT_INF = 0x3f3f3f3f; const int INT_M_INF = 0x7f7f7f7f; const ll LL_INF = 0x3f3f3f3f3f3f3f3f; const ll LL_M_INF = 0x7f7f7f7f7f7f7f7f; const double pi = acos(-1.0); const double EPS = 1e-6; const int dx[] = {0, 0, -1, 1}; const int dy[] = {-1, 1, 0, 0}; const ll MOD = 1e9 + 7; const int MAXN = 10 + 10; const int MAXT = 10000 + 10; using namespace std; int T, n; char tu[MAXN][MAXN]; int main(){ int kase = 0; scanf("%d", &T); while(T--){ scanf("%d", &n); for(int i = 0; i < n; ++i) scanf("%s", tu[i]); for(int i = 0; i < n; ++i) for(int j = 0; j < n; ++j){ if(tu[i][j] != ‘.‘) continue; for(char ch = ‘A‘; ch <= ‘Z‘; ++ch){ bool flag = true; for(int k = 0; k < 4; ++k) if(i + dx[k] >= 0 && i + dx[k] < n && j + dy[k] >= 0 && j + dy[k] <= n && tu[i + dx[k]][j + dy[k]] == ch){ flag = false; break; } if(flag){ tu[i][j] = ch; break; } } } printf("Case %d:\n", ++kase); for(int i = 0; i < n; ++i) printf("%s\n", tu[i]); } return 0; }
时间: 2024-11-07 07:05:26