Portal
博弈题。并不是
s
g
sg
sg题,而且直接的脑子博弈。设输入为
a
,
b
,
c
,
d
a,b,c,d
a,b,c,d。
首先若
b
=
c
=
d
=
0
b=c=d=0
b=c=d=0,直接判断即可。
若不是,那么
a
a
a的作用就是每次减
1
1
1,所以先不考虑它,即先把它当做
0
0
0来考虑。而若只剩下了
b
,
c
,
d
b,c,d
b,c,d,那么只有两种操作,
b
−
=
2
,
c
+
=
1
b-=2,c+=1
b−=2,c+=1或
b
−
−
,
c
−
−
b--,c--
b−−,c−−,显然真正起决定作用的是
b
b
b这个值。
先不考虑
c
c
c的影响,那么其实就是一个经典的博弈模型,即
b
%
3
=
=
0
b\%3==0
b%3==0则先手必败,否则先手必胜。若加上了
c
c
c的影响,可以发现若
c
>
0
c>0
c>0,则其实就没有影响,若
c
=
0
c=0
c=0,那么就先走一步,然后就转化成了前面的情况,这样同样也可以判断了。
最后考虑加上
a
a
a的影响。可以发现偶+必胜和奇+必败一定是必胜态(前面指
a
a
a的奇偶性,后面指后三个数形成的局面的状态),原因是这两者都一定可以使得对方只能处于偶+必败这个状态,同时也可以看出偶+必败一定是必败态。
关键是有一个状态需要特殊考虑,就是奇+必胜这个状态。若奇+必胜态想要成为必胜态,那么一定是双方不停地扔给对方奇+必胜这个状态,最后先手为奇+必败这个状态,而这个结合上述种种情况,可以发现附加条件就为
b
%
3
=
=
2
&
&
c
>
1
b\%3==2 \&\& c>1
b%3==2&&c>1,证明挺显然的。
那么这题就做完了,时间复杂度为
O
(
1
)
O(1)
O(1)的,是一道很纯粹的脑子博弈题目。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
int stack[20];
inline void write(int x)
{
if(x<0){putchar('-');x=-x;}
if(!x){putchar('0');return;}
int top=0;
while(x)stack[++top]=x%10,x/=10;
while(top)putchar(stack[top--]+'0');
}
inline void pr1(int x){write(x);putchar(' ');}
inline void pr2(int x){write(x);puts("");}
int main()
{
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
int T=read();
for(int t=1;t<=T;t++)
{
int a=read(),b=read(),c=read(),d=read();
printf("Case #%d: ",t);
if(b==0 && c==0 && d==0)
{
if(a&1 || a==0)puts("Horse");
else puts("Rabbit");
}
else
{
int id=-1,pd=0;
if(c==0)
{
if(b<2)id=0;
else b-=2,c=1,pd=1;
}
if(id==-1)
{
if(b%3==0)id=0;
else id=1;
}id^=pd;
if(a&1)pd=0;
else pd=1;
if(b%3==2 && c>1 && id==1)id=0;
else id^=pd;
if(id==0)puts("Rabbit");
else puts("Horse");
}
}
return 0;
}