一个N*N的网格,初始为白色。现在有一个K*K的印章,每次操作:你可以用印章把网格中一个K*K的子矩形染成黑色或白色。如果一个格子被多次染色,那么后一次染色会覆盖掉前一次的。现在,给你N*N的由黑白两色构成的图案board(board[i][j]为第i行第j列格子的颜色,不是白字母‘W’表示,就是黑由字母‘B’表示),问是否能通过若干次操作,将网格从初始状态染成图案board的样子。如果可以输出"Possible",否则输出"Impossible".
Input
多组测试数据,第一行一个整数T,表示测试数据数量,1<=T<=5 每组测试数据有相同的结构构成: 每组数据一行两个整数N与K,其中1<=K<=N<=20。 之后N行,每行N个字符,表示board,字符都由‘W’与‘B’构成。
Output
每组数据一行输出,即是否可能染出board图案来。
Input示例
3 4 3 BBBW BWWW BWWW WWWW 2 2 BW WB 6 2 BWBWBB WBWBBB BWBWBB WBWBBB BBBBBB BBBBBB
Output示例
Possible Impossible Possible#include <iostream> #include <algorithm> #include <cstring> using namespace std; const int MAXN = 25; char input[MAXN][MAXN]; bool vis[MAXN][MAXN]; int t, n, k; int main() { cin >> t; int sumA, sumB; while (t--) { cin >> n >> k; memset(vis, 0, sizeof(vis)); bool flag = true; for (int i = 0; i < n; i++) { cin >> input[i]; } while (flag) { flag = false; for (int i = 0; i <= n - k; i++) { for (int j = 0; j <= n - k; j++) { sumA = 0; sumB = 0; bool found = false; for (int l = i; l < i + k; l++) { for (int r = j; r < j + k; r++) { if (vis[l][r]) { continue; } found = true; if (input[l][r] == 'B') { sumA++; } else { sumB++; } } } if ((sumA == 0 || sumB == 0) && found) { flag = true; for (int l = i; l < i + k; l++) { for (int r = j; r < j + k; r++) { vis[l][r] = true; } } } } } } flag = true; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (!vis[i][j] && input[i][j] == 'B') { flag = false; } } } if (flag) { cout << "Possible" << endl; } else { cout << "Impossible" << endl; } } return 0; }