• 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;
    }
  • 相关阅读:
    素数算法问题
    字符指针和字符数组
    指针引用多维数组
    指针细节整理3
    指针细节整理2
    指针细节整理
    公约数和公倍数
    冒泡排序、选择排序
    如何写出高性能的sql语句?
    并发控制
  • 原文地址:https://www.cnblogs.com/zhangjiuding/p/7906160.html
Copyright © 2020-2023  润新知