您的位置:首页 > 其它

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

2014-03-22 20:38 232 查看
题目链接: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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: