poj 1082 Calendar Game 博弈论dp

//poj 1082
//sep9
#include <iostream>
using namespace std;
int dp[200][14][33];

int month_day(int y,int m)
{
	if(y%4==0&&y%100!=0||y%400==0)
		if(m==2)
			return 29;
	if(m==1||m==3||m==5||m==7||m==8||m==10||m==12)
		return 31;
	if(m==2)
		return 28;
	return 30;
}


bool valid_day(int y,int m,int d)
{
	if(y>2001)
		return false; 
	if(y<1900)
		return false;
	if(m>12)
		return false;
	if(m<1)
		return false;
	int td=month_day(y,m);
	if(d>td||d<1)
		return false;
	if(y==2001&&y==12)
		return false;
	if(y==2001&&y==11&&d>4)
		return false;
	return true;
}

void next_day(int y,int m,int d,int& ny,int& nm,int& nd)
{
	if(valid_day(y,m,d+1))
		ny=y,nm=m,nd=d+1;
	else if(valid_day(y,m+1,1))
		ny=y,nm=m+1,nd=1;
	else if(valid_day(y+1,1,1))
		ny=y+1,nm=1,nd=1;
	else
		ny=-1;	
}

void next_month(int y,int m,int d,int& ny,int& nm,int &nd)
{
	if(valid_day(y,m+1,d))
		ny=y,nm=m+1,nd=d;
	else if(y==12&&valid_day(y+1,1,d))
		ny=y+1,nm=1,nd=d;
	else 	
		ny=-1;
}

int main()
{
	int cases;
	int ny,nm,nd;
	memset(dp,0,sizeof(dp));
	dp[2001-1900][11][4]=0;
	for(int y=2001;y>=1900;--y)
		for(int m=12;m>=1;--m)
			for(int d=31;d>=1;--d){
				if(!valid_day(y,m,d))
					continue;
				int ny1,nm1,nd1;
				int ny2,nm2,nd2;
				next_day(y,m,d,ny1,nm1,nd1);
				next_month(y,m,d,ny2,nm2,nd2);
				int cnt=0;
				if(ny1 !=-1)	
					if(dp[ny1-1900][nm1][nd1]==0)
						++cnt;
				if(ny2!=-1)
					if(dp[ny2-1900][nm2][nd2]==0)
						++cnt; 
				dp[y-1900][m][d]=cnt>0?1:0;
			}
	scanf("%d",&cases);
	while(cases--){
		int y,m,d;
		scanf("%d%d%d",&y,&m,&d);
		if(dp[y-1900][m][d]>0)
			puts("YES");
		else
			puts("NO");
	}
	return 0;	
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值