「赛后总结」CSP-S 2020

题目/题解

T1

出题人一定有很多马。

对询问离线,一年一年的加。

期望得分:90

实际得分:40

在考场上我竟然觉得自己能调出来/xk

二分答案所在的年份,然后 day by day 的增加天数计算具体哪一天。

100pts:

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
typedef long long ll;

int min(int a, int b) { return a < b ? a : b; }

ll r;
int q, y, m, d;
int ny[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int sy[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

bool issy(int x) {
    bool flag1 = (x % 400 == 0);
    bool flag2 = ((x % 4 == 0) && (x % 100 != 0));
    return flag1 || flag2;
}

bool isry(int x) {
    if (x < 0 && (0 - x - 1) % 4 == 0) return true;
    if (x > 0 && x <= 1582 && x % 4 == 0) return true;
    if (x > 1582) return issy(x);
    return false;
}

ll check(int y, ll tot = 0) {
    int bf = min(0, y) + 4713;
    int ry = (bf + 3) / 4;
    tot += 1ll * bf * 365 + 1ll * ry;
    if (y <= 0) return tot;
    int af = y - 1;
    if (af >= 1582) {
        ry = 1582 / 4;
        tot += 1ll * 1582 * 365 + 1ll * ry - 1ll * 10;
        if (af == 1582) return tot;
        int now = 1582;
        while (now < af) {
            ++now;
            if (issy(now)) tot += 1ll * 366;
            else tot += 1ll * 365;
            if (now == af || now == 1600) break;
        }
        if (now == af) return tot;
        af -= 1600;
        ry = af / 4 - af / 100 + af / 400;
        tot += 1ll * af * 365 + 1ll * ry;
        return tot;
    }
    else {
        ry = af / 4;
        tot += 1ll * af * 365 + 1ll * ry;
    }
    return tot;
}

int main() {
    scanf("%d", &q);
    while (q--) {
        scanf("%lld", &r); y = 0;
        int L = -4713, R = 1e9 + 518;
        while (L <= R) {
            int mid = (L + R) >> 1;
            if (check(mid) > r) R = mid - 1;
            else y = mid, L = mid + 1;
        }
        r -= check(y);
        m = 1, d = 1;
        while (r--) {
            if (y == 1582 && m == 10 && d == 4) d = 15;
            else ++d;
            bool typ = isry(y);
            if (typ) {
                if (d > sy[m]) {
                    ++m, d = 1;
                    if (m > 12) {
                        ++y, m = 1;
                        if (y == 0) y = 1;
                    }
                }
            }
            else {
                if (d > ny[m]) {
                    ++m, d = 1;
                    if (m > 12) {
                        ++y, m = 1;
                        if (y == 0) y = 1;
                    }
                }
            }
        }
        if (y < 0) printf("%d %d %d BC\n", d, m, -y);
        else printf("%d %d %d\n", d, m, y);
    }
    return 0;
}

T2

用 map 直接 T 飞,离散化+数组最慢才300+ms,话说为啥要打标记啊/kk

\(a_1,a_2,\dots,a_n\) 表示已有的宠物。

那么根据 \(a_1 \& a_2\& \dots \& a_n\) 可以得到购买饲料的序列。

得到了购买饲料的序列就可以知道编号的二进制位上哪些可以为 \(1\)(设有 \(num\) 个),哪些只能为 \(0\),答案就是 \(2 ^{num} - n\)。小心爆 unsigned long long

期望得分:100

实际得分:60

100pts:

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <map>
#define M 1000001

unsigned long long x, bt;
int n, m, c, k, cp[69];

unsigned long long qpow(int a, int b) {
    unsigned long long ans = 1, base = a;
    while (b) {
        if (b & 1) ans = ans * base;
        base = base * base;
        b >>= 1;
    }
    return ans;
}

int main() {
    scanf("%d %d %d %d", &n, &m, &c, &k);
    bt = 0;
    for (int i = 1; i <= n; ++i) {
        scanf("%llu", &x);
        bt |= x;
    }
    for (int i = 1, p, q; i <= m; ++i) {
        scanf("%d %d", &p, &q);
        ++cp[p];
        if (bt & (1ull << p)) --cp[p];
    }
    int pnum = 0;
    for (int i = k - 1; i >= 0; --i) {
        if (cp[i] == 0) ++pnum;
    }
    if (pnum == 64) {
        if (n != 0) std::cout << qpow(2, 63) - n + qpow(2, 63) << '\n';
        else puts("18446744073709551616");
    }
    else std::cout << qpow(2, pnum) - n << '\n';
    return 0;
}

T3

期望得分:10

实际得分:10

T4

期望得分:0

实际得分:0

总结

用了太多时间在 T1 上,T2没有好好检查,T3、T4暴力没有好好写。

题目读的不认真,T1 有一年十月少了十天一开始不知道(浪费了 30min 调代码),T2 考完试之后才知道 q 互不相同。

posted @ 2020-11-08 20:28  yu__xuan  阅读(106)  评论(0编辑  收藏  举报