HDU 1760 A New Tetris Game(dfs + 博弈)

题目链接:HDU 1760 A New Tetris Game

分析转自:http://blog.csdn.net/hjd_love_zzt/article/details/10900097

必胜态:从当前状态所能到达的状态中存在一个必败态
必败态:从当前状态所能达到的状态全部是必胜态
本题状态:当前整个棋盘的状态
由题意确定的必败态:不能再放的为必败态
解决方法:对当前状态A(此时的整个棋盘),每个可以
放的位置放上一个,然后去判定此状态B是否必败,若
必败,那么当前状态A为必胜态。若所有的可以走到的
状态B都是必胜态,那么当前状态A为必败态。无路可走
的也肯定是必败态。递归结束便可得到结果,返回0必败
返回1必胜。

#include<map>
#include<string>
#include<iostream>
#include<stdio.h>

using namespace std;

//一个状态若有一个子状态为必败态,则此状态为必胜态
//dfs
map<string,int>sg;//0表示不存在,存在则返回value
map<string,bool>is;//1表示存在 0表示不存在
int n,m;

bool judge(string str,int i,int j)
{
    if(str[i * m + j] == '1' || str[i * m + j + 1] == '1' || str[i * m + m + j] == '1' || str[i * m + m + j + 1] == '1')
        return false;
    return true;
}
void input(string &str,int i,int j)
{
    str[i * m + j]=str[i * m + j + 1]=str[i * m + m + j] = str[i * m + m + j + 1] = '1';
}
int DFS(string str)
{
    //若存在
    if(is[str])
    return sg[str];
    //若不存在
    for(int i = 0;i < n - 1;i++)
    {
        for(int j = 0;j < m - 1;j++)
        {
            //当前点可行
            if(judge(str,i,j))
            {
                //下一颗子
                string temp = str;
                input(temp,i,j);
                //子状态存在必败态
                if(DFS(temp) == 0)
                {
                    //此状态为必胜状态,标记
                    is[str] = 1;
                    sg[str] = 1;
                    return 1;
                }
            }
        }
    }
    //此状态为必败状态,标记
    is[str] = 1;
    sg[str] = 0;
    return 0;
}
int main()
{
    string str;
    string temp;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        str="";
        sg.clear();
        is.clear();
        for(int i = 0;i < n;i++)
        {
            cin >> temp;
            str += temp;
        }
        if(DFS(str))
            printf("Yes\n");
        else
            printf("No\n");
    }
    return   0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值