棋盘问题(翻转)

文章讨论了一个问题,给定一个n×n的棋盘,棋子按黑白交替排列,通过最少的棋子颜色反转操作,使得所有棋子颜色一致。使用深度优先搜索策略和编程实现解决此问题。
摘要由CSDN通过智能技术生成

题目描述

有n×n的正方形棋盘,每个格子里的棋子要么是黑色向上,要么是白色向上,当把一个格子里的棋子颜色改变(黑→白或者白→黑)时,其周围上下左右(如果存在的话)的格子里的棋子颜色也被反转!

问至少反转几个棋子可以使棋盘上的全部棋子变为白色或者黑色向上?

输入

输入第一行为一个整数n(1≤n≤16),随后n行n列描述棋盘,其中b代表黑色,w代表白色。

输出

输出一个整数即翻转次数。若无法完成,则输出“Impossible”。

AC代码:

#include <iostream>
using namespace std;
int map[20][20];
const int inf = 0x7fffffff;
int n,ans = inf;

void fz(int x,int y){
    map[x - 1][y] ^= 1;
    map[x][y - 1] ^= 1;
    map[x][y] ^= 1;
    map[x][y + 1] ^= 1;
    map[x + 1][y] ^= 1;
}


void dfs(int row,int step,int value)
{
    if(row == n + 1)
    {
        for(int i = 1;i <= n;i ++){
            if(map[n][i] == value)
                return;
        }
        ans = min(step,ans);
        return;
    }
    int v = 0;
    for(int i = 1;i <= n;i ++){
        if(map[row - 1][i] == value){
            step++;
            fz(row,i);
            v = v | (1 << (i - 1));
        }
    }
    dfs(row + 1,step,value);
    for(int i = 1;i <= n;i ++){
        if((v >> (i - 1)) & 1)
            fz(row,i);
    }
}


int main()
{
    cin >> n;
    char ch;
    for(int i = 1;i <= n;i ++){
        for(int j = 1;j <= n;j ++){
            cin >> ch;
            map[i][j] = (ch == 'b');
        }
    }

    for(int k = 0;k < (1 << n);k ++)
    {
        for(int i = 1;i <= n;i ++){
            map[0][i] = (k >> (i - 1)) & 1;
        }
        dfs(1,0,0);
        dfs(1,0,1);
    }

    if(ans != inf) cout << ans << endl;
    else cout << "Impossible" << endl;
    return 0;
}

运行结果

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
棋盘覆盖问题是指:给定一个大小为2^n × 2^n的棋盘和一个特殊方格(称为特殊点),用L型骨牌覆盖棋盘上除特殊点以外的所有方格,使得任何2个L型骨牌都不重叠,且所有L型骨牌都覆盖棋盘上的方格。其中L型骨牌由3个小正方形组成,可以旋转或翻转。 以下是棋盘覆盖问题的代码及伪代码: ``` #include<bits/stdc++.h> using namespace std; const int N=1<<7; int n,ans,x,y; int a[N][N]; void dfs(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4,int id) { if(id==0) return ; int len=1<<(id-1),cnt=0; if(x1>=x&&x1<=x+len&&y1>=y&&y1<=y+len) cnt++; if(x2>=x&&x2<=x+len&&y2>=y&&y2<=y+len) cnt++; if(x3>=x&&x3<=x+len&&y3>=y&&y3<=y+len) cnt++; if(x4>=x&&x4<=x+len&&y4>=y&&y4<=y+len) cnt++; if(cnt==0) { dfs(x1,y1,x1+len-1,y1+len-1,x1,y1+len,len-1,y1+len,id-1); dfs(x2,y2,x2,y2+len-1,x2+len-1,y2,len-1,y2+len,id-1); dfs(x3,y3,x3+len-1,y3,x3,y3+len,x3+len-1,y3+len,id-1); dfs(x4,y4,x4,y4,x4+len-1,y4+len-1,x4+len,y4+len,id-1); } else { if(cnt!=4) ans++; if(cnt==3) { if(x1<x||x1>x+len||y1<y||y1>y+len) dfs(x2,y2,x2,y2+len-1,x2+len-1,y2,len-1,y2+len,id-1),dfs(x3,y3,x3+len-1,y3,x3,y3+len,x3+len-1,y3+len,id-1),dfs(x4,y4,x4,y4,x4+len-1,y4+len-1,x4+len,y4+len,id-1); if(x2<x||x2>x+len||y2<y||y2>y+len) dfs(x1,y1,x1+len-1,y1+len-1,x1,y1+len,len-1,y1+len,id-1),dfs(x3,y3,x3+len-1,y3,x3,y3+len,x3+len-1,y3+len,id-1),dfs(x4,y4,x4,y4,x4+len-1,y4+len-1,x4+len,y4+len,id-1); if(x3<x||x3>x+len||y3<y||y3>y+len) dfs(x2,y2,x2,y2+len-1,x2+len-1,y2,len-1,y2+len,id-1),dfs(x1,y1,x1+len-1,y1+len-1,x1,y1+len,len-1,y1+len,id-1),dfs(x4,y4,x4,y4,x4+len-1,y4+len-1,x4+len,y4+len,id-1); if(x4<x||x4>x+len||y4<y||y4>y+len) dfs(x2,y2,x2,y2+len-1,x2+len-1,y2,len-1,y2+len,id-1),dfs(x3,y3,x3+len-1,y3,x3,y3+len,x3+len-1,y3+len,id-1),dfs(x1,y1,x1+len-1,y1+len-1,x1,y1+len,len-1,y1+len,id-1); } else if(cnt==2) { if(!(x1>=x&&x1<=x+len&&y1>=y&&y1<=y+len)) swap(x2,x3),swap(y2,y3); if(!(x4>=x&&x4<=x+len&&y4>=y&&y4<=y+len)) swap(x2,x4),swap(y2,y4); if(!(x2>=x&&x2<=x+len&&y2>=y&&y2<=y+len)) swap(x3,x4),swap(y3,y4); dfs(x3,y3,x3+x2-x4-x,y3+y2-y4-y,x3+x-x4-x+max(0,min(len-x+min(x-x2,len-x-x2),len)),y3+y-max(0,min(len-y+min(y-y2,len-y-y2),len)),id-1); dfs(x3+x2-x4-x+max(0,min(len-x+min(x-x2,len-x-x2),len)),y3+y-max(0,min(len-y+min(y-y2,len-y-y2),len)),x2,y2,x+x2-x4-x+max(0,min(len-x+min(x-x4,len-x-x4),len)),y+y2-y4-y+max(0,min(len-y+min(y-y4,len-y-y4),len)),id-1); dfs(x+x-len+x-x2+x-x+x-x+x,0,x+x-len+x-x+x-x+x,0,0,len-id,0,id-len); dfs(0,0,0,len-id,0,len-id,0,0,id-len); } else if(cnt==1) { if(x3>=x&&x3<=x+len&&y3>=y&&y3<=y+y+y-len) dfs(x+x-len+x-x3,0,x+x-len+x-x+x-len+x-x+x,0,0,len-id,0,id-len), dfs(x+x-len+x-x+x-len+x-x+x,0,x-len+x-x+x-len+x-len+x,0,id-len,len-id,0,id-len), dfs(0,0,0,len-id,0,len-id,0,0,id-len), dfs(0,len-len+y-y+y-y+y-y-y+y-y+y-y+y-len,0,len-id,len-id,len-id,len-id,0,id-len), dfs(0,len-len+y-y+y-y+y-y-y+y-y+y-y+y-len+max(0,min(len-y+min(y-y3,len-y-y3),len)),x+(max(0,min(len-x+min(x-x3,len-x-x3),len))),y,max(0,min(len-y+min(y-y3,len-y-y3),len))),x+(max(0,min(len-x+min(x-x3,len-x-x3),len))),len+y+y-len+max(0,min(len-y+min(y-y3,len-y-y3),len)),id-1; else dfs(x,len-len+x-x+x-len,0,len-id,max(0,min(len-x+min(x-x3,len-x-x3),len))),len+(max(0,min(len-y+min(y-y3,len-y-y3),len))),x+(max(0,min(len-x+min(x-x3,len-x-x3),len))),len+y-max(0,min(len-y+min(y-y3,len-y-y3),len)),id-1), dfs(0,0,0,len-id,0,len-id,0,0,id-len), dfs(len-len+x-x+max(0,min(len-x+min(x-x3,len-x-x3),len))),len+(max(0,min(len-y+min(y-y3,len-y-y3),len))),len,len-id,max(0,min(len-x+min(x-x3,len-x-x3),len))),len+(max(0,min(len-y+min(y-y3,len-y-y3),len))),len,max(0,min(len-x+min(x-x3,len-x-x3),len)))),id-len; } } } int main() { cin>>n>>x>>y; a[x][y]=a[x][y+1]=a[x+1][y]=a[x+1][y+1]=-10000; dfs(0,0,(n<<=n)-len,n<<=n,(n>>=n)-len,n>>=n,(n>>=n)-len,n>>=n,n); cout<<ans; return 0; } ``` 伪代码如下: ``` void chessboard_covering(int x_left_top,int y_left_top,int x_right_bottom,int y_right_bottom,int x_special,int y_special) { if(size=left_top corner to right_bottom corner equals 2) { // 使用一种确定的方法覆盖整个棋盘(如将特殊点放在左上角,第一次填充使用右下角方格) return; } else { // 找到中心点的位置 int x_center=(x_left_top+x_right_bottom)/2; int y_center=(y_left_top+y_right_bottom)/2; // 计算中心点的id int id_center=(size/2)*(size/2)+offset(id_center_x,id_center_y,size/2); // 递归地处理四个子问题 chessboard_covering(...); // 左上角子问题 chessboard_covering(...); // 右上角子问题 chessboard_covering(...); // 左下角子问题 chessboard_covering(...); // 右下角子问题 } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值