标签:
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1079
题目大意:
有一个日期游戏,胜利时间是2001年11月4日。玩家可以从当前日期移动到下一天,也可以移动到
下一个月的今天,比如从2000年3月3日可以移动到2000年3月4日,也可以移动到2000年4月3日。
当然,移动到下一个月的当前日期的前提是那一天是存在的,比如说2001年1月31日,只能移动到
2001年2月1日,而不能移动到2001年2月31日,因为那天不存在。问:给你一个日期,玩家是否能
依靠上述规则,从当前日期移动到2001年11月4日从而赢得比赛。
思路:
这是一道博弈题,2001年11月4日是个必败点,能到这一天的点都是必胜点。应该是用博弈P/N分
析,不过通过几组日期找到了规律。。。
2001年11月4日中11+4 = 15是奇数,为必败点。而必胜点2001年11月3日中11+3 = 14为偶数,
和2001年10月4日中10+4 = 14也为偶数。则可以考虑必胜点都为月份+当月日期为偶数的点。都
是能达到奇数的偶数点。平年还是闰年不影响奇偶改变,但是9月30日和11月30日虽然是奇数点,
但是能到达偶数点也能达到奇数点,比如说9月30日能到10月1日(奇数点)也能到10月30日(偶数点),
同理11月30日也是能到奇数点也能到达偶数点,所以9月30日和11月30日都为必胜点。
那么结论就是:只要 月份 + 当月日期 == 偶数,或者日期为9月30日或是11月30日,都为必胜点,
其他的都为必败点。
AC代码:
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; int A[14] = {0,31,29,31,30,31,30,31,31,30,31,30,31}; int B[14] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; int IsDay(int year,int month,int day) { if((year%4==0&&year%100 != 0) || year % 400 == 0) { if(day > A[month]) return 0; return 1; } else { if(day > B[month]) return 0; return 1; } } int main() { int T; scanf("%d",&T); while(T--) { int year,month,day; scanf("%d%d%d",&year,&month,&day); if((month+day)%2==0 || (month == 9 && day == 30) || (month == 11 && day == 30)) printf("YES\n"); else printf("NO\n"); } return 0; }
HDU1079 POJ1082 Calendar Game【博弈】
标签:
原文地址:http://blog.csdn.net/lianai911/article/details/44937265