画家问题

2016-08-10  本文已影响0人  qratosone

http://cxsjsxmooc.openjudge.cn/test/Y/

代码

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using std::cin;
using std::cout;
using std::endl;
int map[20][20];//草稿
int copy[20][20];//原始记录
int line[20];//第一行
char col[20];//输入缓冲区
int n;
int min;
int count;
void draw(int x,int y){//画画并且增加次数
    map[x][y]=!map[x][y];
    map[x-1][y]=!map[x-1][y];
    map[x+1][y]=!map[x+1][y];
    map[x][y-1]=!map[x][y-1];
    map[x][y+1]=!map[x][y+1];
    count++;
}
bool guess(){
    //从第二行开始 判断每个点上边的点是否为黄色 如果不是黄色 则涂该点
    for(int i=2; i<=n; i++)
        for(int j=1; j<=n; j++)
            if(map[i-1][j] == 0)
                draw(i,j);


    //判断最后一行是否都为黄色 如果是则记录次数 否则提交失败
    for(int k=1; k<=n; k++)
        if(map[n][k] != 1)
            return false;
    if(count < min)
        min = count;
    return true;
}
void getLine(int k){
    //二进制枚举第一行
    int j=n;
    while(j>0){
        line[j]=k%2;
        k/=2;
        j--;
    }
}
int main(){
    int w;
    cin>>w;
    while(w--){
        cin>>n;
        min=n*n+1;
        for (int i = 1; i <=n; ++i) {
            scanf("%s",col);
            //一行一行扫描
            for (int j = 1; j <=n ; ++j) {
                if(col[j-1]=='w'){
                    copy[i][j]=0;
                }
                else{
                    copy[i][j]=1;
                }
            }
        }
        //开始枚举
        for (int k = 0; k <pow(2,n) ; ++k) {
            count=0;
            memcpy(map,copy, sizeof(copy));
            getLine(k);
            //枚举第一行
            for (int i = 1; i <=n ; ++i) {
                if(line[i]==1){
                    draw(1,i);
                }
            }
            guess();
        }
        if(min!=n*n+1){
            cout<<min<<endl;
        }
        else{
            cout<<"inf"<<endl;
        }
    }
    return 0;
}
上一篇下一篇

猜你喜欢

热点阅读