poj1753

介绍了如何解决POJ 1753的棋盘翻转问题,通过暴力枚举的方法,对4x4棋盘进行操作,使其全部变为同一颜色。使用了6x6棋盘简化边界条件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开始刷poj,从初级开始,枚举题1753,题目简短的来说就是一个棋盘,4x4的,有黑白棋两种,
问输入一个棋盘,最少需要翻多少回棋子(每次翻一个,但其上下左右的棋子跟着会变化)
使得整个棋盘全部白色或者全部黑色。

菜鸟一个并没有什么好的想法,想了一会后开始看别的大神们的思路(特别感谢優YoU http://user.qzone.qq.com/289065406/blog/1299076400),选择了一种自己能理解的方法:就是暴力枚举,一共16个棋子,每个棋子翻奇数次就等同于翻1次,翻偶数次就等同于翻0次,所有情况如下:翻0次,翻一个棋子,翻2个棋子,翻3个棋子。。。翻16个棋子。翻0次就是直接去检查是否满足情况,翻一次一共有16种选择,所以有两个类似于计数器一样的变量,step和deep,step表示翻转次数,暴力枚举所以是0~16,而deep表示的是在某次数下对16个棋子的选择,比如step等于三,此时就是假设总共翻转三回,deep从0~3,选择第一个棋子翻,翻完后再选择,一共选择三步,结果不对返回,选择第一个棋子不翻。。

还有个重点是虽然是4x4的棋盘,但是用的是6x6的,只用中心位置,这样简化代码,对于边角上的棋子翻转不需要单独分类。
下面是用c写的代码:

#include <stdio.h>
#include <stdlib.h>
//输入棋盘4X4,黑白两种棋;翻一块棋其上下左右跟着翻动
int b[6][6]={0};
int r[5]={-1,1,0,0,0};
int c[5]={0,0,-1,1,0};
int flag;
int step;
int judge_all(void){
    int i,j;
    for(i=1;i<5;i++){
        for(j=1;j<5;j++)
            if(b[i][j]!=b[1][1])
            return 0;
    }
    return 1;
}
void flip(int row,int col){
int i;
for(i=0;i<5;i++)
    b[row+r[i]][col+c[i]]=!b[row+r[i]][col+c[i]];
    return;
}
void dfs(int row,int col,int deep){
    if(deep==step)
   {
       flag=judge_all();
       return;
   }
    if(flag||row==5)
        return;

    flip(row,col);
    if(col<4)
    dfs(row,col+1,deep+1);
    else
    dfs(row+1,1,deep+1);

    flip(row,col);//翻回来
    if(col<4)
      dfs(row,col+1,deep);
    else
      dfs(row+1,1,deep);

      return;
}
int main()
{

    char s[6];
    int i=1;
    for(i;i<=4;i++){
    int j=0;
    scanf("%s",s);
    for(j;j<4;j++)
    {
        if(s[j]=='b')
            b[i][j+1]=1;
    }
    }
    for(step=0;step<=16;step++){
        dfs(1,1,0);
        if(flag) break;
    }
    if(flag) printf("%d\n",step);
    else
    printf("Impossible\n");
    return 0;
}

过了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值