ACdream群OJ 1131 Apple 博弈

来源:互联网 发布:tt域名cc域名 编辑:程序博客网 时间:2024/05/17 08:54

题目大意:整理为,现在有两个数字n和m,两人每轮可以使得n++或者m++(有且必须选其一),第一个让n^m>=A的人为输。问第一个人是必输、必赢或平局。

思路:先用的sg求,发现平局没法表示。最后直接用0表示必输点、1表示必赢点、2表示平局。

问题的关键在于终止条件的判断。显然当 n>=2 && m>=2时候 子状态是有限且很少的,可以暴力询问所有子状态。

当n==1时,m其实可以取无限大。但是,发现当 (n+1)^m>=A时候,子状态只有一个,而且,显然这种状态为平局。

当m==1时,n<=A,状态有限但是太多。但是当n^(m+1)>=A,子状态只有一个,可以直接通过A-n的奇偶性判断此点状态。

特别的,当一开始n^m>=A时候,是先手必败。

//#pragma comment(linker, "/STACK:102400000,102400000")#include<cstdio>#include<cstring>#include<vector>#include<queue>#include<cmath>#include<cctype>#include<string>#include<algorithm>#include<iostream>#include<ctime>#include<map>#include<set>using namespace std;#define MP(x,y) make_pair((x),(y))#define PB(x) push_back(x)typedef long long LL;//typedef unsigned __int64 ULL;/* ****************** */const int INF=100011122;const double INFF=1e100;const double eps=1e-8;const LL mod=20120427;const int NN=10;const int MM=1000010;/* ****************** */map<pair<int,int>,int>Mmap;int cnt;LL A;int sg[1000000];//0:lose//1:win//2:pingpair<int,int>temp;// n^m >= Abool fun(int n,int m){    if(n==1)    {        if(1>=A)            return true;        return false;    }    LL x=1;    while(m--)    {        x=x*n;        if(x>=A)            return true;    }    return false;}int solve(int n,int m){    temp=MP(n,m);    int id;    if(Mmap.count(temp)==0)    {        id=++cnt;        sg[id]=-1;        Mmap[temp]=id;    }    else        id=Mmap[temp];    if(sg[id]!=-1)return sg[id];    if(fun(n,m))    {        sg[id]=1;        return sg[id];    }    if(n==1 && fun(n+1,m))    {        sg[id]=2;        return sg[id];    }    if(m==1 && fun(n,m+1))    {        sg[id]=1-( (A-n)%2 );        return sg[id];    }    int x1=solve(n+1,m);    int x2=solve(n,m+1);    if(x1==0 || x2==0)        sg[id]=1;    else    {        if(x1==1 && x2==1)            sg[id]=0;        else            sg[id]=2;    }    return sg[id];}int main(){    int x,z;    int n,m;    while(scanf("%d%d%d",&n,&m,&z)!=EOF)    {        Mmap.clear();        cnt=0;        A=z;        if(fun(n,m))        {            puts("lose");            continue;        }        x=solve(n,m);      //  printf("cnt==%d\n",cnt);        if(x==0)            puts("lose");        else if(x==1)            puts("win");        else            puts("draw");    }    return 0;}


0 0
原创粉丝点击