HDU1079记忆化搜索sg函数

题意不说了,博弈题,可以找规律 ,这里用的是dfs+sg函数打表,不过数据不是很强,还是有瑕疵。

sg函数一般可以暴力打表
也可以使用DFS,这题不能用暴力,只能用dfs记忆化搜索

DFS搜索+SG函数模板

下面的两份代码差不多一样,还有瑕疵,有空的时候再看看。

代码一:

/*
 * @Author: hesorchen
 * @Date: 2020-07-03 17:05:01
 * @LastEditTime: 2020-07-16 20:40:50
 * @Description: https://hesorchen.github.io/
 */
#include <map>
#include <set>
#include <list>
#include <queue>
#include <deque>
#include <cmath>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define endl '\n'
#define PI acos(-1)
#define PB push_back
#define ll long long
#define INF 0x3f3f3f3f
#define mod 1000000007
#define pll pair<ll, ll>
#define lowbit(abcd) (abcd & (-abcd))
#define max(a, b) ((a > b) ? (a) : (b))
#define min(a, b) ((a < b) ? (a) : (b))

#define IOS                      \
    ios::sync_with_stdio(false); \
    cin.tie(0);                  \
    cout.tie(0);
#define FRE                              \
    {                                    \
        freopen("in.txt", "r", stdin);   \
        freopen("out.txt", "w", stdout); \
    }

inline ll read()
{
    ll x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    return x * f;
}
//head==============================================================================

ll sg[120][14][35]; //年份-1900 、月份 、日期
ll calendar[13];

void init()
{
    fill(sg[0][0], sg[0][0] + 120 * 14 * 35, -1);
    sg[101][11][4] = 0;
    calendar[1] = 31;
    calendar[2] = 28;
    calendar[3] = 31;
    calendar[4] = 30;
    calendar[5] = 31;
    calendar[6] = 30;
    calendar[7] = 31;
    calendar[8] = 31;
    calendar[9] = 30;
    calendar[10] = 31;
    calendar[11] = 30;
    calendar[12] = 31;
}
void make_calendar(ll yy)
{
    yy += 1900;
    if (yy % 400 == 0 || (yy % 100 != 0 && yy % 4 == 0))
        calendar[2] = 29;
    else
        calendar[2] = 28;
}
bool check(ll y, ll m, ll d)
{
    if (m >= 1 && m <= 12)
    {
        make_calendar(y);
        if (calendar[m] >= d && d >= 1)
            return 1;
    }
    return 0;
}
ll dfs(ll yy, ll mm, ll dd)
{
    if (sg[yy][mm][dd] != -1)
        return sg[yy][mm][dd];
    if (yy > 101 || (yy == 101 && mm > 11) ||
        (yy == 101 && mm == 11 && dd > 4))
        return 1;
    ll tempy, tempm, tempd;
    tempy = yy, tempm = mm, tempd = dd + 1;
    make_calendar(yy);
    if (tempd > calendar[tempm])
    {
        tempd = 1;
        tempm++;
        if (tempm > 12)
        {
            tempm = 1;
            tempy++;
        }
    }
    if (dfs(tempy, tempm, tempd) == 0)
        return sg[yy][mm][dd] = 1;
    tempy = yy, tempm = mm + 1, tempd = dd;
    if (tempm > 12)
    {
        tempm = 1;
        tempy++;
    }
    if (check(tempy, tempm, tempd) && dfs(tempy, tempm, tempd) == 0)
        return sg[yy][mm][dd] = 1;
    return sg[yy][mm][dd] = 0;
}
int main()
{
    init();
    ll t;
    cin >> t;
    while (t--)
    {
        ll y, m, d;
        cin >> y >> m >> d;
        y -= 1900;
        if (dfs(y, m, d))
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;
}

/*  
1
1900 1 1 

*/

代码二:

/*
 * @Author: hesorchen
 * @Date: 2020-07-03 17:05:01
 * @LastEditTime: 2020-07-16 23:11:04
 * @Description: https://hesorchen.github.io/
 */
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;

int sg[2100][13][33];
int calendar[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool isleap(int y)
{
    if (y % 400 == 0 || (y % 100 != 0 && y % 4 == 0))
        return true;
    return false;
}

bool check(int y, int m, int d)
{
    if (isleap(y) && m == 2)
    {
        if (d <= 29)
            return true;
        else
            return false;
    }
    if (d <= calendar[m])
        return true;
    else
        return false;
}

int dfs(int y, int m, int d)
{
    if (sg[y][m][d] != -1)
        return sg[y][m][d];
    if (y == 2001 && m == 11 && d == 4)
        return sg[y][m][d] = 0;
    if (y > 2001)
        return sg[y][m][d] = 1;
    else if (y == 2001 && m > 11)
        return sg[y][m][d] = 1;
    else if (y == 2001 && m == 11 && d > 4)
        return sg[y][m][d] = 1;
    int tempy, tempm, tempd;
    tempy = y, tempm = m, tempd = d + 1;
    if (isleap(y) && m == 2)
    {
        if (tempd == 30)
        {
            tempm = 3;
            tempd = 1;
        }
    }
    else
    {
        if (tempd > calendar[tempm])
        {
            tempd = 1;
            tempm++;
            if (tempm > 12)
                tempy++, tempm = 1;
        }
    }
    if (dfs(tempy, tempm, tempd) == 0)
        return sg[y][m][d] = 1;
    tempy = y, tempm = m + 1, tempd = d;
    if (tempm > 12)
        tempy++, tempm = 1;
    if (check(tempy, tempm, tempd) && dfs(tempy, tempm, tempd) == 0)
        return sg[y][m][d] = 1;
    return sg[y][m][d] = 0;
}

int main()
{
    memset(sg, -1, sizeof(sg));
    int y, m, d;
    int T;
    scanf("%d", &T);
    while (T--)
    {
        scanf("%d%d%d", &y, &m, &d);
        if (dfs(y, m, d))
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hesorchen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值