zoukankan      html  css  js  c++  java
  • 「赛后总结」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
    ", d, m, -y);
            else printf("%d %d %d
    ", 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) << '
    ';
            else puts("18446744073709551616");
        }
        else std::cout << qpow(2, pnum) - n << '
    ';
        return 0;
    }
    

    T3

    期望得分:10

    实际得分:10

    T4

    期望得分:0

    实际得分:0

    总结

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

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

  • 相关阅读:
    恢复IE下载对话框[转]
    意外删除Oracle数据文件(dbf),恢复oralce库的解决办法Oracle错误代码:ORA01033
    [转].net的一些问题
    解决了一个ASP.NET无法接受中文参数值的情况
    修改IIS6的默认设置,扩充上传文件的大小
    在ASP.NET中Request取不到正确的中文参数问题解决办法[base64编码/解码]
    使用微软的TreeView控件有的客户端有脚本错误的问题
    [转]几种调用WebService的方法
    电脑操作精典密芨60式 【转】
    初始化时间下列框的脚本
  • 原文地址:https://www.cnblogs.com/poi-bolg-poi/p/13945670.html
Copyright © 2011-2022 走看看