描述
Adam和Eve玩一个游戏,他们先从1900.1.1到2001.11.4这个日期之间随意抽取一个日期出来。然后他们轮流对这个日期进行操作:
1 : 把日期的天数加1,例如1900.1.1变到1900.1.2
2 : 把月份加1,例如:1900.1.1变到1900.2.1
其中如果天数超过应有天数则日期变更到下个月的第1天。月份超过12则变到下一年的1月。而且进行操作二的时候,如果有这样的日期:1900.1.31,则变成了1900.2.31,这样的操作是非法的,我们不允许这样做。而且所有的操作均要考虑历法和闰年的规定。
谁先将日期变到2001.11.4谁就赢了。
每次游戏都是Adam先操作,问他有没有必胜策略?
格式
输入格式
一个测试点。多组数据。
第一行为数据组数。
接下来一行X Y Z表示X年Y月Z日
输出格式
输出“YES”or“NO”表示亚当是否有必胜策略。
样例1
样例输入1
3
2001 11 3
2001 11 2
2001 10 3
样例输出1
YES
NO
NO
提示
建议先把所有情况都算出来^_^
1、题目分析:
首先,对于选出来的日期,两个人对该日期轮流进行两种操作中的任意一种,也就是说每个人的每一次操作都可以任意选择两种操作中的任意一种,而不是拘泥与某一种顺序。这一点要搞清楚,我一开始就陷入了误区。
其次,注意游戏规则,日期、月份自动逢满进一;类似与1.31的日期不允许对月份进行操作。
最后,问题是对于给定的日期,有没有胜利的策略,即选定策略后进行若干操作,Adam将日期加到了2001.11.14
2、思路:
题目提示,先将所有的情况都算出来。
一开始我以为是告诉我要用最笨的方法将所有可能的结果算出来并存储,然后对于输入的数据挨个进行判断,看到大佬的分析才明白是另外的意思。
因为先将日期加到2001.11.4的人赢,所以选择11.4的话Adam失败,往前推11.3、11.1、10.30·····和10.4、8.4···都可以,此时(month+day)是偶数;而11.2、10.31、9.4等不可以,此时(month+day)是奇数。即两种操作是对month和day做出的操作,那么一般情况下(month+day)的奇偶性是依次变化的,所以我们可以认为(month+day)为偶数时,Adam可以成功,(month+day)为奇数时,Adam会失败,与year无关(orz,给出题人跪了)。
那么会不会用特殊情况呢?有的。因为(month+day)为偶数时,是可以赢得,所以只需要考虑那些(month+day)为奇数中的特殊点即可。
2.29:①2.29->3.1 因为3.1是可以赢得,所以2.29输
②2.29->3.29 因为3.29是可以赢得,所以2.29输
所以2.29输
8.31:因为9月只有30天,只能对日期进行操作。
8.31->9.1 9.1可以赢,所以8.31输
10.31,12.31同
9.30:9.30->10.1 因为10.1一定输,所以9.30可以赢
11.30同
所以有两个特例,即:9.30和11.30
#include <iostream>
using namespace std;
int main()
{
int N;
cin>>N;
int year,month,day;
for(int i=0;i<N;i++)
{
cin>>year>>month>>day;
if(month==9&&day==30)
cout<<"YES"<<endl;
else if(month==11&&day==30)
cout<<"YES"<<endl;
else if((month+day)%2==0)
cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}