poj1681 画家问题

A:画家问题


总时间限制:

    1000ms

内存限制:

    65536kB


描述

    有一个正方形的墙,由N*N个正方形的砖组成,其中一些砖是白色的,另外一些砖是黄色的。Bob是个画家,想把全部的砖都涂成黄色。

    但他的画笔不好使。当他用画笔涂画第(i, j)个位置的砖时, 位置(i-1, j)、 (i+1, j)、 (i, j-1)、 (i, j+1)上的砖都会改

    变颜色。请你帮助Bob计算出最少需要涂画多少块砖,才能使所有砖的颜色都变成黄色。

输入

    第一行是个整数t(1≤t ≤20),表示要测试的案例数。然后是t个案例。每个案例的首行是一个整数n (1≤n ≤15),表示墙的大小。接下

    来的n行表示墙的初始状态。每一行包含n个字符。第i行的第j个字符表示位于位置(i,j)上的砖的颜色。“w”表示白砖,“y”表示黄砖。

输出

    每个案例输出一行。如果Bob能够将所有的砖都涂成黄色,则输出最少需要涂画的砖数,否则输出“inf”。

样例输入


    2

    3

    yyy

    yyy

    yyy

    5

    wwwww

    wwwww

    wwwww

    wwwww

    wwwww


样例输出


    0

    15

========================================================================

eg.


#include <iostream>

#include <cstdio>

#include <cmath>

using namespace std;


int t = 0;

int n = 0;

char col[20];

bool c[20][20] = {0};

bool colored[20][20] = {0};

bool swit[20][20] = {0};


void changeswit(int a, int b)

{

    colored[a][b] = !colored[a][b];

    colored[a - 1][b] = !colored[a - 1][b];

    colored[a + 1][b] = !colored[a + 1][b];

    colored[a][b - 1] = !colored[a][b - 1];

    colored[a][b + 1] = !colored[a][b + 1];

}



int main()

{

    scanf("%d", &t);

    for(int ti = 1; ti <= t; ++ti)

    {

        int sum = 0;

        scanf("%d", &n);

        int 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] == 'y') c[i][j] = 1;

                else c[i][j] = 0;

            }

        }

        for(int k = 0; k < pow(2.0, n); k++)

        {

            for(int i = 1; i <= n; i++)

                for(int j = 1; j <= n; j++)

                {

                    colored[i][j] = c[i][j];

                }

            for(int i = 1; i <= n; i++)

            {

                swit[1][i] = (k>>(i - 1)) & 1;

                if(swit[1][i])

                {

                    changeswit(1, i);

                    sum++;

                }

            }

            for(int i = 2; i <= n; i++)

                for(int j = 1; j <= n; j++)

                    if(!colored[i - 1][j])

                    {

                        swit[i][j] = 1;

                        sum++;

                        changeswit(i, j);

                    }

            int mark = 0;

            for(int j = 1; j <= n; j++)

                if(!colored[n][j]) mark = 1;

            if(!mark && sum < min) min = sum;

            sum = 0;

        }

        if(min != n*n + 1) printf("%d\n",min);

        else printf("inf\n");

    }

    return 0;

}


转载于:https://my.oschina.net/locusxt/blog/131868

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值