Calendar Game

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;
}
上一篇:CodeGo.net>如何测试方法抛出特定输入异常


下一篇:c#-测试工具与测试框架有什么不同/