Zoj 1024 Calendar Game

题目来源:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=24

模拟

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int IsWin[102][13][32];//如果值为1表明 亚当赢,0表明 亚当输,初始时为-1
int Month_Day[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int Judge(int y, int m, int d)
{
    if(y > 101 || (y == 101 && (m > 11 || (m == 11 && d > 4))))
        return 1;
    if(y == 101 && m == 11 && d == 4)
        return 0;
    if(IsWin[y][m][d] == -1)
    {
        int win = 0;
        if(m != 12)
        {
            if(d <= Month_Day[m] || (d == 29 && m == 1 && (((y % 4 == 0) && (y % 100)) || (y % 400 == 0)) && y != 0))
                if(Judge(y, m+1, d) == 0)
                    win = 1;
        }
        else if(Judge(y+1, 1, d) == 0)
            win = 1;

        if(win == 0)
        {
            if(d < Month_Day[m])
                win = 1 - Judge(y, m, d+1);
            else if(m != 12)
                win = 1 - Judge(y, m+1, 1);
            else
                win = 1- Judge(y+1, 1, 1);
        }
        IsWin[y][m][d] = win;
    }
    return IsWin[y][m][d];
}
int main()
{
    int T;
    cin>>T;
    int y, d, m;
    while(T--)
    {
        memset(IsWin, 0xff, sizeof(IsWin));
        scanf("%d %d %d", &y, &m, &d);
        if(Judge(y-1900, m, d) == 1)
            cout<<"YES"<<endl;
        else
            cout<<"NO"<<endl;
    }
    return 0;
}

网上还有的思想,把他看成博弈:

获得胜利的一方必须翻倒2001年11月4日;
下面是观察推论结果,11月4日,11+4=15是奇数。由于无论是加
一天还是加一个月都会改变m+d的奇偶性,除了下面几个特例
2月28日、9月30日和11月30日,显然如果m和d是这三个日子的话
则先行者必胜:
2月28日到3月28日
9月30日到10月1日
11月30日到12月1日
剩下的只有当m+d为偶数时先行者必胜。
没有其他的特殊情况!

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;


int main()
{
    int T;
    int y, m, d;
    cin>>T;
    while(T--)
    {
        scanf("%d %d %d", &y, &m, &d);
        if(m == 2 && d == 28)
        {
            printf("YES\n");
            continue ;
        }
        else if(m == 9 && d == 30)
        {
            printf("YES\n");
            continue ;
        }
        else if(m == 11 && d == 30)
        {
            printf("YES\n");
            continue ;
        }
        else if((m+d)%2 == 0)
        {
            printf("YES\n");
            continue ;
        }
        printf("NO\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值