51nod 1448 二染色问题 (逆向考虑)

题目:

 

 

 

 

 

注意,这题不是把一块区域的黑翻成白、白翻成黑。

 

是把一块区域全部翻成白或者翻成黑。

初始为全白,看能否翻出题中的情况。

 

 

我们假设翻转若干次能得到图中的形状,那么我们找出最后一次的翻转,即全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;
}

 

posted @ 2017-11-27 21:19  ninding  阅读(304)  评论(0编辑  收藏  举报