题目大意:
就是现在两个人在玩一个日历, 初始选定一个起点日期然后两人轮流操作, 每次可以选择跳到下一天或者下一个月对应的同一天, 但是当下一个月没有这一天是不能选择跳到下一个月
比如1月31不能跳到2月31, 因为没有
那么到达2001年11月4日的人胜利, 游戏过程中如果谁超出这个日期就输了, 初始位置选定在1900年1月1日到2001年11月4日之间, 问先手是否会胜利是就Yes否则No
大致思路:
就是一个非常简单的NP点的问题, 就是换成在日期上转移而已, 将非法日期都视为N点, 与处理处所有的日子的NP值即可, 当起点是P点时先手败否则胜
没什么难度= =
代码如下:
Result : Accepted Memory : 1660 KB Time : 0 ms
/* * Author: Gatevin * Created Time: 2015/4/28 19:40:43 * File Name: Rin_Tohsaka.cpp */ #include<iostream> #include<sstream> #include<fstream> #include<vector> #include<list> #include<deque> #include<queue> #include<stack> #include<map> #include<set> #include<bitset> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<cctype> #include<cmath> #include<ctime> #include<iomanip> using namespace std; const double eps(1e-8); typedef long long lint; #define foreach(e, x) for(__typeof(x.begin()) e = x.begin(); e != x.end(); ++e) #define SHOW_MEMORY(x) cout<<sizeof(x)/(1024*1024.)<<"MB"<<endl #define base 1900 bool np[110][13][32]; int Days[13] = {-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; bool leap(int year) { if(year % 100 == 0) { if(year % 400 == 0) return true; return false; } if(year % 4 == 0) return true; return false; } bool right(int year, int month, int day)//判断是否日期合法 { if(year == 2001) { if(month > 11) return false; if(month == 11 && day >= 4) return false; }//超出终点了 if(year < 1900) return false;//小于起点 if(leap(year) && month == 2 && day == 29)//闰年的2月29 return true; if(day > Days[month]) return false; return true; } bool nextday(int year, int month, int day)//注意非法日期的np都是0 { if(leap(year)) { if(month == 2 && day == 29) return np[year - base][3][1]; if(month == 2 && day == 28) return np[year - base][2][29]; } if(month == 12 && day == 31) return np[year + 1 - base][1][1]; if(day + 1 > Days[month]) return np[year - base][month + 1][1]; return np[year - base][month][day + 1]; } bool nextmonth(int year, int month, int day)//非法日期的np值都是0 { if(month == 12) return np[year + 1 - base][1][day]; return np[year - base][month + 1][day]; } int main() { memset(np, 0, sizeof(np)); np[2001 - base][11][4] = 1;//=1表示为P点, 0表示是N点 for(int i = 2001; i >= 1900; i--) for(int j = 12; j >= 1; j--) for(int k = 31; k >= 1; k--) { if(!right(i, j, k)) continue; bool p = nextday(i, j, k) || nextmonth(i, j, k);//有没有可到P点的路 if(p) np[i - base][j][k] = 0; else np[i - base][j][k] = 1; } int T; scanf("%d", &T); while(T--) { int year, month, day; scanf("%d %d %d", &year, &month, &day); if(np[year - base][month][day]) printf("NO\n"); else printf("YES\n"); } return 0; }