题目描述:
Teresa 和 Eureka 玩游戏,有n个糖果 ( 1 <= n <= 1000000 且n为奇数 ) ,两人轮流取糖果吃,可以吃1、2、3个糖果,不能不吃,谁最后总共吃了奇数块糖果就算赢,输的那一方要请赢的人看愤怒的小鸟大电影,假设两人像PQ那样机智(咦PQ是谁?喷泉?),问对于任意合法的 n ,先手能否胜利?
输入格式:
一个整数T,代表用例组数。
每组用例一行,一个整数 n ( 1 <= n <= 1000000 且n为奇数 ) ,表示初始有 n 个糖果。
输出格式:
对于每组用例,若先手必胜输出“first win”,否则输出“first lost”。
样例输入:
3
1
3
5
样例输出:
first win
first win
first lost
题目大意:
有一堆奇数个糖果,每个人可以选择拿1,2,3个,最后有奇数个糖果的获胜,问有没有先手必胜策略
解题思路:
dp[i][j]为还剩i个糖果时,手里有奇数或者偶数(j=1奇,0偶)是否有必胜策略(1有,0无)
dp[i][j]=sigema(dp[i-k][对手奇偶]==0)>0(k=1,2,3)就是说在自己可以取到的状态里有一个是对手的必败态,自己就必胜,否则自己必败
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <cmath>
#include <map>
#include <queue>
#include <string>
#include <set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int INF=0x3f3f3f3f;
#define CLR0(a) (memset(a,0,sizeof(a)))
#define CLR1(a) (memset(a,-1,sizeof(a)))
#define CLRf(a) (memset(a,0x3f,sizeof(a)))
const int maxn=0;
const int maxm=0;
int dp[1000050][2];
int main()
{
dp[0][0]=0;
dp[0][1]=1;
dp[1][0]=1;
dp[1][1]=0;
dp[2][0]=1;
dp[2][1]=1;
for(int i=3;i<=1000000;i++)
{
int op=!(i%2);
for(int j=1;j<=3;j++)
{
if(dp[i-j][op]==0)
{
dp[i][0]=1;
break;
}
}
op=!op;
for(int j=1;j<=3;j++)
{
if(dp[i-j][op]==0)
{
dp[i][1]=1;
break;
}
}
}
int n;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
printf("first %s\n",dp[n][0]?"win":"lost");
}
return 0;
}