Calendar Game
题意
给你一个日期,你每次可以移动一天或者移动一个月,如果移动一个月的日期补存在,你只能移动一天。移动到2001.11.4的人获胜,移动到以后的人失败。
思路
考虑到2001.11.4 是个必败态,可以考虑它是由什么状态转移过来的,直接sg(我死了)。后面实在写不下去了,分类讨论的种类太多,我停止了思考,后面看题解,发现可以找规律做,不管是月份加一,还是日期加一,都改变了奇偶性,那么目标日期是11月4日,为奇数。初始日期如果为偶数的话,先者必胜。但还得考虑到特殊情况,9月30日,和11月30日和,它俩本来是奇数,而而且移动一步不会改变奇偶性,所以还是胜利。如果中间出现了特殊数字怎么办?这是个伪命题,获胜的人不会给这个机会。
Sg代码
#include<iostream>
#define mem(a,b) memset(a,b,sizeof(a))
#include<string.h>
//#include<bits/stdc++.h>
//#define inf 0x3f3f3f3f
//#define INF 0x7f7f7f7f
//#define endl '\n'
//#define debug(case,x); cout<<case<<" : "<<x<<endl;
//#define open freopen("ii.txt","r",stdin)
//#define close freopen("oo.txt","w",stdout)
//#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
//#define pb push_back
//#define ll long long
//#define lson rt<<1
//#define rson rt<<1|1
using namespace std;
int sg[500][20][40];
int day[400];
int mm[15]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int g(int y , int m , int d)
{
if(sg[y][m][d]!=-1) return sg[y][m][d];
int flag=0;
if(y>101) return sg[y][m][d]=0;
if(m==2 && d==day[y] || m<12 && mm[m]==d && mm[m+1]>=d)
{
int a=g(y,m+1,d) , b=g(y,m+1,1);
if(a==0 || b==0) return sg[y][m][d]=1;
else if(a && b) return sg[y][m][d]=0;
}
else if(m<12 && mm[m]==d && mm[m+1]<d)
{
int a=g(y,m+1,1);
if(a==0) return sg[y][m][d]=1;
else return sg[y][m][d]=0;
}
else if(m==2 && d<day[y] || m<12 && d<mm[m] || m==12 && d<mm[12])
{
int a=g(y,m,d+1) , b=g(y , m+1 , d);
if(a==0 || b==0 ) return sg[y][m][d]=1;
else if(a && b) return sg[y][m][d]=0;
}
else if(m==12 && d==mm[12])
{
int a=g(y+1 ,1 ,1) , b=g(y+1 ,1, d);
if(a==0 || b==0) return sg[y][m][d]=1;
else if(a && b) return sg[y][m][d]=0;
}
}
void init()
{
mem(sg,-1);
for(int i=1900;i<=2001;i++)
if(i%4==0&&i%100!=0||i%400==0) day[i-1900+1]=29;
else day[i-1900+1]=28;
sg[101][11][4]=0;
for(int i=5;i<=mm[11];i++) sg[101][11][i]=1;
for(int i=1;i<=mm[12];i++) sg[101][12][i]=1;
}
int main()
{
int t,y,m,d;
init();
cin>>t;
while(t--)
{
cin>>y>>m>>d;
y-=1900;
g(y,m,d);
if(sg[y][m][d]==1) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
找规律,分奇,偶。
#include<iostream>
#define mem(a,b) memset(a,b,sizeof(a))
#include<string.h>
//#include<bits/stdc++.h>
//#define inf 0x3f3f3f3f
//#define INF 0x7f7f7f7f
//#define endl '\n'
//#define debug(case,x); cout<<case<<" : "<<x<<endl;
//#define open freopen("ii.txt","r",stdin)
//#define close freopen("oo.txt","w",stdout)
//#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
//#define pb push_back
//#define ll long long
//#define lson rt<<1
//#define rson rt<<1|1
using namespace std;
int main()
{
int t,y,m,d;
cin>>t;
while(t--)
{
cin>>y>>m>>d;
if((m+d)%2==0 || m==9 && d==30 || m==11 && d==30)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}