swjtu作业三

围棋由方形网格棋盘和黑白棋子构成。现在棋盘的某方形区域内摆满棋子,下图为该棋盘4*4的区域内摆放棋子的情况。如果用b和w表示该方形网格中棋子的颜色,b为黑色,w为白色。这样该图形可用下面来的矩阵来表示:

bwbw

wwww

bbwb

bwwb

现玩一个游戏,游戏规则是:如果将其中的某一个棋子由黑色变成白色(称为一次变换),则周围四个方向上的棋子将会改变颜色,也就是如果原来棋子的颜色是白色则变成黑色,是黑色则会变成白色。比如上面的棋盘中,将第三行第一个棋子由黑色变成白色,则对应的棋盘会变成下面的颜色:

bwbw

bwww

wwwb

wwwb   

    上述这样的变换称为一次变换。请编写程序,希望通过最少次数的变换将棋盘中的棋子全部变成白色或者黑色。

输入要求:输入第一行为整数n,表示棋盘中放摆放棋子的行数和列数,其后的n行,每行有n个字符,由b和w组成,分别表示棋子的初始颜色。

输出要求:输出1个整数,占1行,表示最少的变换次数。

样例输入:

bwwb
bbwb
bwwb
bwww

样例输出:4

代码如下

#include<iostream>
#include<string>
#include<algorithm> 
using namespace std;

int n;
string *s;
const int NotFound = -1;
const int INF =INT_MAX;
int nxt[][2] = {
    {0,0},{0,1},{0,-1},{1,0},{-1,0}//五个翻转棋子状态
};
void filp(int num)//对n及其周围的棋子进行翻转
{
    int x = num / n;
    int y = num % n;
    for (int i = 0; i < 5; i++)//对自身和周围四颗棋子进行翻转
    {
        int nx = x + nxt[i][0];
        int ny = y + nxt[i][1];

        if (nx < 0 || ny < 0 || nx >= n || ny >= n)
            continue;
        else
        {
            if (s[nx][ny] == 'w')  s[nx][ny] = 'b';
            else s[nx][ny] = 'w';
        }
    }
}
bool trick()
{
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
            if (s[i][j] != s[0][0])
                return false;
    }
    return true;
}
int  dfs(int num, int ans)
{
    if (trick())
        return ans;
    if (num > n*n)
        return INF;
    filp(num);//翻转
    int ans1 = dfs(num + 1, ans + 1);
    filp(num);//翻转回来置为初始状态
    int ans2 = dfs(num + 1, ans);
    return min(ans1, ans2);
}
int main()
{
    cin >> n;
    s = new string[n + 1];
    for (int i = 0; i < n; i++)
        cin >> s[i];
    int res = dfs(0, 0);
    if (res != INF)
        cout << res;
    else
        cout << "Impossible";
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值