题目:
注意,这题不是把一块区域的黑翻成白、白翻成黑。
是把一块区域全部翻成白或者翻成黑。
初始为全白,看能否翻出题中的情况。
我们假设翻转若干次能得到图中的形状,那么我们找出最后一次的翻转,即全W或者全B,让这一块区域置为随机。(随机可以看做B或者W中的一个)
直到把所有的这样的翻转全部找出来,置为随机。
看最后是否有一定是B的点,如果有就说明无法翻转到图中的形状,否则可以翻转。
代码:
#include <iostream> #include <algorithm> #include <map> #include <vector> #include <set> #include <math.h> #include <queue> #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string> using namespace std; typedef long long ll; #define INF 2147483647 int t,n,k; char a[25][25]; //判断以(x,y)为左上角的区域是否为同色,且不全为随机。 bool isSame(int x,int y){ bool flagB = false,flagW = false; for(int i = x;i <= x+k-1; i++){ for(int j = y;j <= y+k-1; j++){ if(a[i][j] == 'B'){ flagB = true; }else if(a[i][j] == 'W'){ flagW = true; } if(flagB && flagW){ return false; } } } if(!flagB && !flagW) return false; return true; } //以(x,y)为左上角的区域置为随机 void makeRandom(int x,int y){ for(int i = x;i <= x+k-1; i++){ for(int j = y;j <= y+k-1; j++){ a[i][j] = 'R'; } } } int main(){ cin >> t; while(t--){ cin >> n >> k; for(int i = 1;i <= n; i++) for(int j = 1;j <= n; j++) cin >> a[i][j]; while(true){ bool update = false; for(int i = n-k+1;i >= 1; i--){ for(int j = n-k+1;j >= 1; j--){ // cout << i << " " << j <<endl; if(isSame(i,j)){ makeRandom(i,j); update = true; } } } if(!update) break; } bool flag = true; for(int i = 1;i <= n; i++){ for(int j = 1;j <= n; j++){ if(a[i][j] == 'B'){ flag = false; } } } if(flag){ cout << "Possible" << endl; }else{ cout << "Impossible" << endl; } } return 0; }