hdu 1809(A New Tetris Game(2)) 字符串hash+sg函数+DP

来源:互联网 发布:工业机器人编程软件 编辑:程序博客网 时间:2024/06/11 09:35

题目链接:点击打开链接

题意很简单,用俄罗斯方块填充图形,有些格子有障碍物,最后一个放下方块的人取得胜利,懒得介绍了~

考点是博弈论sg函数的用法~~这个题目难点在于是最多能放下10个俄罗斯正方形~50*50的布局使得单纯的状态压缩无法记录已经搜索过的值,但是初始状态能转化到的所有子状态数量又是有限的~所以这里要用到字符串的hash,我这里是直接用的字典树将状态离散化的~~附上代码~~

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>using namespace std;const int MAXN=60;char chess[MAXN][MAXN];int n,m;void print(){    printf("Debug\n");    for(int i=0;i<n;i++)        puts(chess[i]);}struct hashCode{    const static int SIZE=100000;    struct node_t    {        node_t *son[2];        int idx;    }Node[SIZE];    int toUsed;    inline void init()    {        toUsed=1;        memset(Node,0,sizeof(node_t));    }    inline node_t* _NewNode()    {        memset(Node+toUsed,0,sizeof(node_t));        return Node+toUsed++;    }    inline void insert(const char word[],int data)    {        node_t *loc=Node;        for(int i=0;word[i];i++)        {            int sn=word[i]-'0';            if(!loc->son[sn]) loc->son[sn]=_NewNode();            loc=loc->son[sn];        }        loc->idx=data;    }    inline int find(const char word[])    {        node_t *loc=Node;        for(int i=0;word[i];i++)        {            int sn=word[i]-'0';            if(!loc->son[sn]) return -1;            loc=loc->son[sn];        }        return loc->idx;    }};hashCode dp;inline void to_status(char str[]){    for(int i=0;i<n;i++)        for(int j=0;j<m;j++)            str[i*m+j]=chess[i][j];    str[n*m]='\0';}int dfs(){    char str[MAXN*MAXN];    to_status(str);    int ret=dp.find(str);    if(ret!=-1) return ret;    bool sg[150];    memset(sg,false,sizeof(sg));    for(int i=0;i<n-1;i++)        for(int j=0;j<m-1;j++)            if(chess[i][j]=='0'&&chess[i][j+1]=='0'&&chess[i+1][j]=='0'&&chess[i+1][j+1]=='0')            {                chess[i][j]=chess[i][j+1]=chess[i+1][j]=chess[i+1][j+1]='1';                int sign=dfs();                sg[sign]=true;                chess[i][j]=chess[i][j+1]=chess[i+1][j]=chess[i+1][j+1]='0';            }    while(true)    {        if(!sg[++ret])        {            dp.insert(str,ret);            return ret;        }    }}int main(){    int t;    while(scanf("%d",&t)!=EOF)    {        dp.init();        int sign=0;        for(int i=0;i<t;i++)        {            scanf("%d%d",&n,&m);            for(int j=0;j<n;j++)                scanf("%s",chess[j]);            sign^=dfs();        }        puts(sign?"Yes":"No");    }    return 0;}


原创粉丝点击