HDU 1079 Calendar Game(博弈论 暴力推状态)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1079

解题思路:

P表示先手必胜,N表示先手必败。

当前能够转移到任意一种必败局面的为P

否则为N

剩下就是对年月日月份各种恶心的判断了

代码:

#include<cstdio>
#include<algorithm>

using namespace std;

#define for0(i,a,b) for (int i=a;i<b;i++)
#define for1(i,a,b) for (int i=a;i<=b;i++)

char np[110][13][32];///i从0开始,到101,i+1900=真实年份
                     ///j从1~12
                     ///k从1~31

int mon[2][13] = {{0,31,28,31,30,31,30,31,31,30,31,30,31},{0,31,29,31,30,31,30,31,31,30,31,30,31}};

bool runnian(int x)
{
    x = x+1900;
    return ((x%100!=0 && x%4==0) || (x%400==0) );
}

void prework()
{
    np[101][11][4] = 'N';
    for (int i=101;i>=0;i--){
        bool r = runnian(i);
        for (int j=(i==101)?11:12;j>=1;j--){
            for (int k=(i==101&&j==11)?3:mon[r][j];k>=1;k--){
                int day1 = (k==mon[r][j])? 1:k+1;
                int month1 = j + (day1==1);
                if (month1==13) month1=1;
                int year1 = (day1==1 && month1==1)? i+1:i;

                ///判断下一个月是否存在这一天
                int day2 = k;
                int month2 = (j==12)? 1:j+1;
                int year2 = (month2==1)? i+1:i;
                if (mon[runnian(year2)][month2]>=k && (year2<101 ||(year2==101 && year2<=11))){///这两天都可以取到
                    if (np[year1][month1][day1]=='N'||np[year2][month2][day2]=='N') np[i][j][k] = 'P';
                    else np[i][j][k] = 'N';

                }
                else {///只能取下一天
                    if (np[year1][month1][day1]=='N') np[i][j][k] = 'P';
                    else np[i][j][k] = 'N';
                }
            }
        }
    }
}

int main()
{
    int T;
    scanf("%d",&T);
    while (T--){
        int y,m,d;
        scanf("%d %d %d",&y,&m,&d);
        if (np[y-1900][m][d]=='P') printf("YES\n");
        else printf("NO\n");
    }

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值