Flip Game POJ1753

http://poj.org/problem?id=1753;

首先要想到所有情况可以穷尽,可以用枚举。答案范围为0~16步,列出1,2....16步的所有可能,如果存在正确情况就输出结束程序,否则一直枚举到16步为止。核心枚举思想是让每一个棋子都做一次第一步操作的棋子。


#include <stdio.h>
#include <iostream>
using namespace std;


int flag,Map[4][4],step;


int range()
{
    for(int i=0;i<4;i++)
        for(int j=0;j<4;j++)
            if(Map[i][j]!=Map[0][0]) return 0;
    return 1;
}


void turn(int i,int j)
{
    Map[i][j]=!Map[i][j];
    if(i>0) Map[i-1][j]=!Map[i-1][j];
    if(i<3) Map[i+1][j]=!Map[i+1][j];
    if(j>0) Map[i][j-1]=!Map[i][j-1];
    if(j<3) Map[i][j+1]=!Map[i][j+1];
}


void DFS(int i,int j,int dp)
{


    if(dp==step){
        flag=range();
        return;
    }//比如这次要枚举3步的所有情况,dp表示已经操作的步数,当dp==step==3时,判断条件是否达成(即flag的赋值)


    if(flag||i==4) return;//如果上一步达成条件或已枚举所有情况则结束程序;


    turn(i,j);
    if(j<3) DFS(i,j+1,dp+1);
    else DFS(i+1,0,dp+1);//第一个turn表示让这个位置的棋子作为当前dp步的棋子;


    turn(i,j);
    if(j<3) DFS(i,j+1,dp);
    else DFS(i+1,0,dp);/第二个turn表示让这个棋子还原,让它的下一个位置作为dp步的棋子;


    return;考虑到枚举完都找不到的情况,用这句话退出,其实可以去掉,写上去好理解;
}


int main()
{
    char c;
    for(int i=0;i<4;i++)
        for(int j=0;j<4;j++)
    {
         scanf(" %c",&c);
         if(c=='b') Map[i][j]=1;
         else Map[i][j]=0;
    }
    for(step=0;step<=16;step++)
    {
        flag=0;
        DFS(0,0,0);
        if(flag) break;
    }
    if(flag) printf("%d\n",step);
    else printf("Impossible\n");


}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值