poj 1753——Flip Game

13 篇文章 0 订阅

题意:4×4的棋盘上有一些黑白棋,要求翻多少个子能翻成全黑或者全白

思路:dfs,翻哪个棋子顺序不影响,所以最多2的16次方种可能

用状态压缩来表示每个位置,第0位表示(0,0),第1位表示(0,1),以此类推

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

char field[5][5];

const int dir[4][2]={-1,0,0,1,1,0,0,-1};

const int allblack=(1<<16)-1;


int trans(int i,int j)
{
        return i*4+j;
}

void untrans(int p,int &i,int &j)
{
        i=p/4;
        j=p%4;
}

inline bool judge(int x,int y)
{
        if(x>=4||x<0)return false;
        if(y>=4||y<0)return false;
        return true;
}

int ans;

void dfs(const int sta,int step,int x,int y)
{
        if(sta==0||sta==allblack){
                if(ans==-1||ans>step)ans=step;
                return ;
        }
        if(x>=4||y>=4)return;
        int change=sta;
        int tmp=trans(x,y);
        change^=(int)(1<<tmp);
        for(int i=0;i<4;++i){
                int tx=x+dir[i][0];
                int ty=y+dir[i][1];
                if(!judge(tx,ty))continue;
                int pos=trans(tx,ty);
                change^=(int)(1<<pos);
        }
        int tx=x;
        int ty=y;
        ty++;
        untrans(trans(tx,ty),tx,ty);
        dfs(sta,step,tx,ty);
        dfs(change,step+1,tx,ty);
}

int main()
{
//        freopen("data.txt","r",stdin);
        int start=0;
        ans=-1;
        for(int i=0;i<4;++i)
        {
                scanf("%s",field[i]);
                for(int j=0;j<4;++j){
                        if(field[i][j]=='b'){
                                int z=trans(i,j);
                                start|=(1<<z);
                        }
                }
        }
        dfs(start,0,0,0);
        if(ans==-1)puts("Impossible");
        else printf("%d\n",ans);
        return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值