Calendar Game HDU - 1079(博弈,打表)

本文介绍了一个基于日历的游戏策略问题,通过递归回溯的方法预计算从任意日期到目标日期2001年11月4日的所有可能路径,并标记每个日期的胜负状态。涉及的日期范围为1900年至2001年,需考虑不同月份及闰年的特殊规则。

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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值