Calendar Game
HDU - 1079题意:在日历表上随机选一天, 然后开始游戏, 游戏规则如下:
1.选择当前的下一天;如:2000/1/3可以转到2000/1/4;
2.选择当前的下一个月的今天; 如:2000/1/28可以转到2000/2/28; 但如果当前是2000/1/31,二月没有31那么该操作不可取;
3.谁先到达20001/11/4,谁胜利;
打表把所有情况的胜负都算出来就行了;
data[i][j][k]表示i/j/k这天的胜负情况;
如果当前天的下一步有必败状态那么现在一定是必胜态,反之就是必败态;
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <stack>
using namespace std;
bool data[2010][15][35];
void init(){
memset(data, true, sizeof(data));
data[2001][11][4]=false;
for(int i=2001; i>=1900; i--){
for(int j=12; j>0; j--){
if(i==2001&&j==12) continue;
for(int k=31; k>0; k--){
if(i==2001&&j==11&&k>=4) continue;
if((j==4||j==6||j==9||j==11)&&k==31) continue;
if(j==2){
if(!(i%4==0&&i%100||i%400==0)&&(k==31||k==30||k==29)) continue;
else if(k==31||k==30) continue;
}
int temp=0, ti, tj, tk;
if(j==4||j==6||j==9||j==11){
if(k==30){
if(data[i][j+1][k]==false) temp=1;
if(data[i][j+1][1]==false) temp=1;
}
else{
if(data[i][j][k+1]==false) temp=1;
if(data[i][j+1][k]==false) temp=1;
}
}
else if(j==2){
if(i%4==0&&i%100||i%400==0){
if(k==29){
if(data[i][j+1][k]==false) temp=1;
if(data[i][j+1][1]==false) temp=1;
}
else{
if(data[i][j][k+1]==false) temp=1;
if(data[i][j+1][k]==false) temp=1;
}
}
else{
if(k==28){
if(data[i][j+1][k]==false) temp=1;
if(data[i][j+1][1]==false) temp=1;
}
else{
if(data[i][j][k+1]==false) temp=1;
if(data[i][j+1][k]==false) temp=1;
}
}
}
else if(j==12){
if(k==31){
if(data[i+1][1][k]==false) temp=1;
if(data[i+1][1][1]==false) temp=1;
}
else{
if(data[i][j][k+1]==false) temp=1;
if(data[i+1][1][k]==false) temp=1;
}
}
else if(j==7){
if(k==31){
if(data[i][j+1][k]==false) temp=1;
if(data[i][j+1][1]==false) temp=1;
}
else{
if(data[i][j][k+1]==false) temp=1;
if(data[i][j+1][k]==false) temp=1;
}
}
else if(j==1){
if(i%4==0&&i%100||i%400==0){
if(k>29){
if(data[i][j+1][1]==false) temp=1;
}
else{
if(data[i][j][k+1]==false) temp=1;
if(data[i][j+1][k]==false) temp=1;
}
}
else{
if(k>28){
if(data[i][j+1][1]==false) temp=1;
}
else{
if(data[i][j][k+1]==false) temp=1;
if(data[i][j+1][k]==false) temp=1;
}
}
}
else{
if(k==31){
if(data[i][j+1][1]==false) temp=1;
}
else{
if(data[i][j][k+1]==false) temp=1;
if(data[i][j+1][k]==false) temp=1;
}
}
data[i][j][k]=temp;
}
}
}
}
int main(){
init();
int T;
scanf("%d", &T);
while(T--){
int y, m, d;
scanf("%d%d%d", &y, &m, &d);
if(y>2001||(y==2001&&m>11)||(y==2001&&m==11&&d>4)) printf("NO\n");
else{
if(data[y][m][d]) printf("YES\n");
else printf("NO\n");
}
}
return 0;
}
本文介绍了一个基于日历的游戏策略问题,通过递归回溯的方法预计算从任意日期到目标日期2001年11月4日的所有可能路径,并标记每个日期的胜负状态。涉及的日期范围为1900年至2001年,需考虑不同月份及闰年的特殊规则。
&spm=1001.2101.3001.5002&articleId=80390831&d=1&t=3&u=0a2dd5331d8c47828ae62ea7789a27cd)

被折叠的 条评论
为什么被折叠?



