当前位置 博文首页 > ttoobne:校赛题解

    ttoobne:校赛题解

    作者:[db:作者] 时间:2021-08-30 10:36

    ?

    A.CQW又迟到了

    水题。

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    #define int ll
    #define INF 0x3f3f3f3f3f3f3f3f
    #define fastio ios::sync_with_stdio(false), cin.tie(0)
    const int mod = 1e9 + 7;
    const int MAXN = 100000 + 10;
    const int MAXM = 100000 + 10;
    
    string s;
    
    signed main()
    {
        fastio;
    
        cin >> s;
        int len = s.length();
        int now;
        for(int i = 0; i < len; i ++) {
            now = i;
            for(int j = 0; j < len; j ++) {
                if(now >= len) now = 0;
                cout << s[now++];
            }
            cout << endl;
        }
    }

    B.CQW的倔强

    水题。

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    #define int ll
    #define INF 0x3f3f3f3f3f3f3f3f
    #define fastio ios::sync_with_stdio(false), cin.tie(0)
    const int mod = 1e9 + 7;
    const int MAXN = 100000 + 10;
    const int MAXM = 100000 + 10;
    
    int n;
    
    int deal(int x)
    {
        int ans = 0;
        while(x) {
            if(x % 10 == 9) ans ++;
            x /= 10;
        }
        return ans;
    }
    
    signed main()
    {
        fastio;
    
        cin >> n;
        int ans = 0;
        for(int i = 1; i <= n; i ++) {
            ans += deal(i);
        }
        cout << ans << endl;
    }

    C.WYS非常方

    n <= 3000 那么枚举两个点即可,那么将两个点同时加上?与该两个点形成的向量垂直的向量?可以形成另外两个点,构成一个正方形,判断另外两个点在不在图中即可。每两个点可以构成两个正方形,因为与两个点形成的向量垂直的向量有两条(两个方向),枚举所有的正方形找最大的即可。

    %:pragma GCC optimize(3)
    #include <algorithm>
    #include <iostream>
    #include <iomanip>
    #include <cstdlib>
    #include <cstring>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <set>
    #include <map>
    using namespace std;
    
    typedef long long ll;
    typedef unsigned long long ull;
    #define PI acos(-1.0)
    #define int ll
    #define INF 0x3f3f3f3f3f3f3f3f
    #define P pair<int, int>
    #define fir first
    #define sec second
    #define fastio ios::sync_with_stdio(false), cin.tie(0)
    const int mod = 998244353;
    const int MAXM = 5000 + 10;
    const int MAXN = 3000 + 10;
    
    int n;
    bool node[MAXM][MAXM];
    int x[MAXN], y[MAXN];
    
    bool judge(int xx, int yy)
    {
        if(xx < 1 || xx > 5000 || yy < 1 || yy > 5000) return false;
        if(node[xx][yy] != 1) return false;
        return true;
    }
    
    int deal(int a, int b)
    {
        int ans = -1;
        int dx = x[b] - x[a];
        int dy = y[b] - y[a];
        swap(dx, dy);
        dx = -dx;
    
        int xa = x[a] + dx, ya = y[a] + dy;
        int xb = x[b] + dx, yb = y[b] + dy;
        if(judge(xa, ya) && judge(xb, yb)) {
            ans = dx * dx + dy * dy;
        }
    
        dx = -dx, dy = -dy;
        xa = x[a] + dx, ya = y[a] + dy;
        xb = x[b] + dx, yb = y[b] + dy;
        if(judge(xa, ya) && judge(xb, yb)) {
            ans = max(ans, dx * dx + dy * dy);
        }
    
        return ans;
    }
    
    signed main()
    {
        fastio;
    
        cin >> n;
        for(int i = 1; i <= n; i ++) {
            cin >> x[i] >> y[i];
            node[x[i]][y[i]] = 1;
        }
    
        int ans = -1;
        for(int i = 1; i <= n; i ++) {
            for(int j = i + 1; j <= n; j ++) {
                if(deal(i, j) != -1) cout << deal(i, j) << endl;
                ans = max(ans, deal(i, j));
            }
        }
        cout << ans << endl;
    }
    
    

    D.绝对强者LYF

    水题。

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    #define int ll
    #define INF 0x3f3f3f3f3f3f3f3f
    #define fastio ios::sync_with_stdio(false), cin.tie(0)
    const int mod = 1e9 + 7;
    const int MAXM = 100000 + 10;
    const int MAXN = 10000 + 10;
    
    int n;
    struct node{
        int a, b, c, d, e;
    } no[MAXN];
    
    int ma, mb, mc, md, me;
    signed main()
    {
        fastio;
    
        cin >> n;
        for(int i = 1; i <= n; i ++) {
            cin >> no[i].a >> no[i].b >> no[i].c >> no[i].d >> no[i].e;
            ma = max(no[i].a, ma);
            mb = max(no[i].b, mb);
            mc = max(no[i].c, mc);
            md = max(no[i].d, md);
            me = max(no[i].e, me);
        }
        for(int i = 1; i <= n; i ++) {
            if(no[i].a >= ma && no[i].b >= mb && no[i].c >= mc && no[i].d >= md && no[i].e >= me){
                cout << i <<endl;
                return 0;
            }
        }
        cout << "WO LYF MEI YOU KAI GUA !" << endl;
    }

    ?

    E.1009的奇思妙想

    ?

    F.CQW的幸福

    放入优先队列中一定不能取 mod !!!

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef unsigned long long ll;
    #define int ll
    #define INF 0x3f3f3f3f3f3f3f3f
    #define fastio ios::sync_with_stdio(false), cin.tie(0)
    const int mod = 998244353;
    const int MAXM = 100000 + 10;
    const int MAXN = 5000000 + 10;
    
    int n;
    int prime[MAXN], judge[MAXN], cnt;
    
    void pre()
    {
        for(int i = 2; i < MAXN; i ++) {
            if(!judge[i]) {
                prime[cnt++] = i;
                for(int j = 2 * i; j < MAXN; j += i) {
                    judge[j] = 1;
                }
            }
        }
    }
    
    priority_queue<int, vector<int>, greater<int> > Q;
    
    signed main()
    {
    //    fastio;
    
        pre();
        cin >> n;
        n *= 2;
        for(int i = 0; i < n; i ++) {
            Q.push(prime[i]);
        }
        int ans = 1;
        for(int i = 1; i <= n; i ++) {
            int temp = Q.top(); Q.pop();
            ans = ((ans % mod) * (temp % mod) % mod) % mod;
            if(temp * temp > n * n) continue;
            Q.push(temp * temp);
        }
        cout << ans % mod << endl;
        return 0;
    }

    ?

    G.FWJ的追求者

    一位二进制可以表示 ?1,两位二进制可以表示?1, 2, 3,三位二进制可以表示?1, 2, 3, 4, 5, 6, 7...

    那么可以发现一个数字 n 二进制有几位,那么就可需要几种硬币构成1 - n。

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    #define int ll
    #define INF 0x3f3f3f3f3f3f3f3f
    #define fastio ios::sync_with_stdio(false), cin.tie(0)
    const int mod = 1e9 + 7;
    const int MAXM = 100000 + 10;
    const int MAXN = 10000 + 10;
    
    int n;
    
    signed main()
    {
        fastio;
    
        int t;
        cin >> t;
        while(t --) {
            cin >> n;
            cout << (int)log2(n) + 1 << endl;
        }
    }

    ?

    H.ZBT的学分

    上来一句:褆爷牛逼!!!orz

    枚举喜欢的活动数量,那么此时只需要考虑必选该活动后,还能凑出 k 个学分的情况数,最后加起来即可。

    具体的,枚举喜欢的活动时,由于必选当前活动,让 k -= 当前枚举的活动的学分,那么接下来就是找能够凑得正好分数为 k 的方法数了。

    接下来问题来了,最大有 32 个活动,减去一个之后剩下?31 个活动,直接枚举 2^31 种情况是不现实的,那么可以将剩下的活动分成两半,每一半的情况数也就最多只有 2^16 种了,将两半的情况能够获得的学分计算出来,枚举第一半的每种情况获得的学分,假设为 x,则第二部分中 k - x 有几个,就有几种情况数使得正好凑够 k 个学分。

    接下来问题又来了,如果我枚举第一个喜欢的活动时,选了另外一个喜欢的活动,那么我枚举到另外那个喜欢的活动时,就会重复计算。怎么去重呢?很好办,开个标记数组即可。枚举到一个喜欢的活动,就把该活动标记,标记过的将不再参与计算,那么在枚举其他活动的时候,就不会出现重复的情况了。

    具体看代码:

    %:pragma GCC optimize(3)
    #include <algorithm>
    #include <iostream>
    #include <iomanip>
    #include <cstdlib>
    #include <cstring>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <set>
    #include <map>
    using namespace std;
    
    typedef long long ll;
    typedef unsigned long long ull;
    #define PI acos(-1.0)
    #define int ll
    #define INF 0x3f3f3f3f3f3f3f3f
    #define P pair<int, int>
    #define fir first
    #define sec second
    #define fastio ios::sync_with_stdio(false), cin.tie(0)
    const int mod = 998244353;
    const int MAXM = (1 << 16) + 10;
    const int MAXN = 32 + 10;
    
    int n, k, m;
    int a[MAXN];
    int use[MAXN];
    
    int cal(int s, int ar[], int len)
    {
        int ans = 0;
        for(int i = 0; i < len; i ++) {
            if((s >> i) & 1) {
                ans += ar[i];
            }
        }
        return ans;
    }
    
    int deal()
    {
        int s = 0, l[MAXM], r[MAXM];
        int b[MAXN], cnt = 0;
        for(int i = 0; i < n; i ++) {
            if(use[i]) continue;
            b[cnt++] = a[i];
        }
    
        int ln = cnt / 2;
        int c[MAXN];
        for(int i = 0; i < ln; i ++) c[i] = b[i];
        for(int i = 0; i < (1 << ln); i ++) {
            l[i] = cal(i, c, ln);
        }
        sort(l, l + (1 << ln));
    
        int rn = cnt - ln;
        for(int i = ln; i < cnt; i ++) c[i-ln] = b[i];
        for(int i = 0; i < (1 << rn); i ++) {
            r[i] = cal(i, c, rn);
        }
        sort(r, r + (1 << rn));
    
        int ans = 0;
        for(int i = 0; i < (1 << ln); i ++) {
            ans += upper_bound(r, r + (1 << rn), k - l[i]) - lower_bound(r, r + (1 << rn), k - l[i]);
        }
        return ans;
    }
    
    signed main()
    {
        fastio;
    
        cin >> n;
        for(int i = 0; i < n; i ++) cin >> a[i];
        cin >> k >> m;
        int ans = 0;
        for(int i = 0; i < m; i ++) {
            int id; cin >> id; id --;
            use[id] = 1;
            k -= a[id];
            ans += deal();
            k += a[id];
        }
        if(!m) ans = deal();
        cout << ans << endl;
    }

    I.SHT的梦想

    防AK,不会,下一个。

    ?

    J.ZBT的游戏

    线段树区间颜色覆盖。

    区间更新时,直接覆盖颜色,当回溯时两个儿子节点颜色不一样则将该点赋值为 INF ,代表该点处覆盖的区间颜色不止一种,懒标记往下推时要注意推到儿子之后要将父亲节点的懒标记赋值为 INF。每次查询将查到的颜色放入 set ,最后输出 set 的 size即可。

    ps: 不要用 cin,cout ,TLE到你怀疑人生。

    %:pragma GCC optimize(3)
    #include <algorithm>
    #include <iostream>
    #include <iomanip>
    #include <cstdlib>
    #include <cstring>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <set>
    #include <map>
    using namespace std;
    
    typedef long long ll;
    typedef unsigned long long ull;
    #define PI acos(-1.0)
    #define int ll
    #define INF 0x3f3f3f3f3f3f3f3f
    #define P pair<int, int>
    #define fir first
    #define sec second
    #define fastio ios::sync_with_stdio(false), cin.tie(0)
    const int mod = 998244353;
    const int MAXM = 1000000 + 10;
    const int MAXN = 100000 + 10;
    
    int n, m, k;
    int tree[MAXN<<2], add[MAXN<<2];
    
    void push(int l, int r, int rt)
    {
        if(add[rt] && add[rt] != INF) {
            tree[rt<<1] = tree[rt<<1|1] = add[rt];
            add[rt<<1] = add[rt<<1|1] = add[rt];
            add[rt] = INF;
        }
    }
    
    void update(int L, int R, int c, int l, int r, int rt)
    {
        if(L <= l && r <= R) {
            tree[rt] = c;
            add[rt] = c;
            return ;
        }
    
        push(l, r, rt);
        int mid = (l + r) / 2;
        if(L <= mid) update(L, R, c, l, mid, rt << 1);
        if(mid < R) update(L, R, c, mid + 1, r, rt << 1 | 1);
    
        if(tree[rt<<1] == tree[rt<<1|1]) tree[rt] = tree[rt<<1];
        if(tree[rt<<1] != tree[rt<<1|1]) tree[rt] = INF;
    }
    
    set<int> S;
    void query(int L, int R, int l, int r, int rt)
    {
        if(L <= l && r <= R) {
             if(l == r) {
                if(tree[rt]) {
                    S.insert(tree[rt]);
                }
                return ;
             }
             if(tree[rt]) {
                if(tree[rt] != INF) {
                    S.insert(tree[rt]);
                    return ;
                }
             }
             else return ;
        }
    
        push(l, r, rt);
        int mid = (l + r) / 2;
        if(L <= mid) query(L, R, l, mid, rt << 1);
        if(mid < R) query(L, R, mid + 1, r, rt << 1 | 1);
    }
    
    signed main()
    {
        scanf("%lld %lld %lld", &n, &m, &k);
        int flag = 0;
        for(int i = 1; i <= m; i ++) {
            char s[20]; scanf("%s", s);
            if(s[0] == 'C') {
                int a, b, c;
                scanf("%lld %lld %lld", &a, &b, &c);
                update(a, b, c, 1, n, 1);
            }
            else {
                int a, b;
                scanf("%lld %lld", &a, &b);
                S.clear();
                query(a, b, 1, n, 1);
                printf("%d\n", S.size());
                flag = 1;
            }
        }
        if(!flag)
            printf("This is a boring game!\n");
    }
    
    /*
    
    老实说,
    要到几岁才开始不相信圣诞老人的存在……
    这类无聊的话题对我而言,
    根本不痛不痒的。
    不过,
    讲到我从几岁起开始不相信圣诞老人就是那个穿着红衣服的老公公时,
    我能确定地说,
    我根本打从一开始就不相信。
    我知道幼稚园圣诞节庆祝会时出现的圣诞老人是假的,
    回溯记忆,
    还能记起周围的幼稚园小朋友都一脸不信任地望着假扮圣诞老人的园长老师。
    即使没有撞见老妈正在亲吻圣诞老公公,
    机灵的我也老早就怀疑只在圣诞节工作的老爷爷是否真的存在了。
    不过,
    我却是过了很久以后,
    才发现外星人、幽灵、妖怪、超能力者以及特摄、动画里头,
    那些与邪恶组织战斗的英雄们并不存在这世上。
    不,
    说不定我早就发现了,
    只不过一直不想承认而已。
    因为,
    在我的内心深处,
    是十分渴望那些外星人、幽灵、妖怪、超能力者以及邪恶组织突然出现在眼前的。
    和我生活的这个普通世界相比,
    特摄、动画里头所描绘的世界,
    反而更有魅力。
    我也想活在那种世界里!
    我真的好想拯救被外星人绑架并关在透明的大型豌豆夹里头的少女…
    也想拿着雷射枪运用智慧与勇气击退企图改写历史的未来人…
    或者光用一句咒语就收拾了恶灵跟妖怪,
    再不然就是和秘密组织的超能力者进行超能力的战斗!
    等等,
    冷静一下,
    假设我被外星人、幽灵、妖怪、超能力者那类的生物袭击,
    没有任何特殊能力的我怎么可能和他们对抗?
    于是,
    我便如是幻想 ——
    某天,
    班上突然转来一个谜样的转学生,
    他其实是个外星人或未来人那类的生物,
    并拥有未知的能力,
    后来他跟坏人战斗,
    而我只要设法让自己被卷进那场战争就好了。
    主要战斗的人是他,
    而我则是追随他的小跟班。
    啊啊,
    实在太棒了,
    我真是聪明啊!
    要不然就是这样。
    某天,
    我那不可思议的力量突然觉醒,
    就像隔空取物或精神念力之类的。
    而且地球上其实还有很多拥有超能力的人类存在,
    自然也会有一个组织专门收容这些人。
    不久之后,
    善良的组织便派人来迎接我。
    而我也成为组织的一员共同对抗企图征服世界的邪恶超能力者。
    不过,
    现实却是意外地残酷。
    现实的生活中,
    并没有半个转学生转来我班上,
    我也没看过UFO…
    就算去了地方上常出现幽灵或妖怪的灵异地点也连个鬼影都没有…
    花了两小时盯着桌上的铅笔,
    它却连一微米都没移动…
    上课时死盯着前座同学的头,
    却怎么样也无法读出他在想什么。
    我就这样边惊叹世界物理法则经常出现的现象,
    边不停自嘲,
    不知从何时起,
    我就开始不看电视上的UFO特别节目或灵异节目了。
    因为不可能会有那种东西……
    不过后来我也成长到仅对那方面的事情存有一丝留恋的程度。
    国中毕业之后,
    我便从那孩提时代的梦想毕业,
    逐渐习惯这个世界的平凡。
    而让我还有一缕期待的一九九九年也没有发生什么事。
    进入二十一世纪后,
    人类依旧无法迈出月球到其他星球去。
    看这情况,
    在我还活着的时候,
    想从地球当天往返阿尔法人马座似乎是不太可能的。
    我脑海中时而幻想着这些事,
    终于也没啥感慨地成为高中生 —— 直到遇到了凉宫春日。
    之后,
    我就这么糊里糊涂地进入学区内的县立高中就读。
    起初我还很后悔,
    因为这座学校位于很高的山上,
    就算是春天也要挥汗如雨地爬上直窜山顶的坡道,
    想轻松健行的那份悠闲早已消失无踪。
    一想到今后三年每天一大早都得这样爬山,
    我的心情就阴郁无比。
    或许是早上差点睡过头的关系,
    走路的速度自然加快许多,
    虽然也曾想过以后干脆早十分钟起床,
    慢慢走去上学就不会这么累,
    不过一想到临起床前的那十分钟睡眠是多么的宝贵,
    我随即放弃了这个念头。
    所以,
    我相信未来的三年还是得持续这个晨间的运动。
    一想到这里,
    心情就更沉重了。
    
    */
    


    ?

    L.SW和ZK的恋爱

    暴力跑一下会发现规律。

    将 n 除以 2 和 5 除 k 次然后在后面加 k 个 0 即可。

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    #define int ll
    #define INF 0x3f3f3f3f3f3f3f3f
    #define fastio ios::sync_with_stdio(false), cin.tie(0)
    const int mod = 1e9 + 7;
    const int MAXM = 100000 + 10;
    const int MAXN = 100000000000000000023 + 10;
    
    int n, k;
    
    bool judge(int x)
    {
        int ans = 0;
        while(x) {
            if(x % 10 != 0) break;
            x /= 10;
            ans ++;
        }
        if(ans >= k) return 1;
        else return 0;
    }
    
    signed main()
    {
        fastio;
        cin >> n >> k;
        if(judge(n)) {
            cout << n << endl;
            return 0;
        }
        int temp = k;
        while(temp --) {
            if(n % 2 == 0) n /= 2;
            if(n % 5 == 0) n /= 5;
        }
        cout << n;
        for(int i = 0; i < k; i ++) cout << 0;
        cout << endl;
    }

    SunW的假期

    水题。

    dfs直接水,也可以一个一个判断。

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    #define int ll
    #define INF 0x3f3f3f3f3f3f3f3f
    #define fastio ios::sync_with_stdio(false), cin.tie(0)
    const int mod = 1e9 + 7;
    const int MAXN = 100000 + 10;
    const int MAXM = 100000 + 10;
    
    string s;
    int op[15] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    
    bool judge(int m, int d)
    {
        if(m == 1 && d == 1) return 1;
        if(m == 2 && d >= 4 && d <= 10) return 1;
        if(m == 4 && d >= 5 && d <= 7) return 1;
        if(m == 5 && d >= 1 && d <= 4) return 1;
        if(m == 6 && d >= 7 && d <= 9) return 1;
        if(m == 9 && d >= 13 && d <= 15) return 1;
        if(m == 10 && d >= 1 && d <= 7) return 1;
        return 0;
    }
    
    void dfs(int m, int d, int ans)
    {
        if(d > op[m]) {
            m ++;
            d = 1;
        }
        if(m > 12) {
            cout << "Happy  New  Year !" << endl;
            return ;
        }
    
        if(judge(m, d)) {
            cout << ans + 1 << endl;
            return;
        }
        dfs(m, d + 1, ans + 1);
    }
    
    void deal()
    {
        if(s == "YD") dfs(1, 2, 0);
        if(s == "CJ") dfs(2, 11, 0);
        if(s == "QMJ") dfs(4, 8, 0);
        if(s == "LDJ") dfs(5, 5, 0);
        if(s == "DWJ") dfs(6, 10, 0);
        if(s == "ZQJ") dfs(9, 16, 0);
        if(s == "GQJ") dfs(10, 8, 0);
    }
    
    signed main()
    {
        fastio;
    
        cin >> s;
        deal();
    }

    ?

    cs