• 2021牛客寒假算法基础集训营3


    2021牛客寒假算法基础集训营3

    A 模数的世界

    a == b == 0直接是0 0 0

    其他的就构造 p - 1,

    x = a + p(p - a - 1) = (p - 1)(p - a), y = (p - 1)(p - b)

    但是可能存在 gcd(p - a, p - b) != 1, 导致构造 p - 1 失败,

    那就让 x 一直 += p * (p - 1) 呗, 知道构造出 p - 1

    int main() {
        IOS;
        for (cin >> _; _; --_) {
            ll a, b, p; cin >> a >> b >> p;
            if (a == 0 && b == 0) { cout << "0 0 0
    "; continue; }
            a += p * (p - a - 1), b += p * (p - b - 1);
            while (__gcd(a, b) % p != p - 1) a += p * (p - 1);
            cout << p - 1 << ' ' << a << ' ' << b << '
    ';
        }
        return 0;
    }
    

    B 内卷

    贪心就行, 先全部都是最低级E, 不断提高当前分数最低的那个人的分数等级就好了, 就几行, 为啥这么少人过啊

    struct { int a[5], deg; } a[N];
    
    int main() {
        IOS; cin >> n >> k; multimap<int, int> st;
        rep (i, 1, n) per (j, 4, 0) cin >> a[i].a[j];
        rep (i ,1, n) st.insert({a[i].a[0], i});
        m = st.rbegin()->first - st.begin()->first;
        while (1) {
            auto it = st.begin(); st.erase(it);
            int x = it->second; ++a[x].deg;
            if (a[x].deg == 4) { if (k) --k; else break; }
            else if (a[x].deg > 4) break;
            st.insert({a[x].a[a[x].deg], x});
            umin(m, st.rbegin()->first - st.begin()->first);
        }
        cout << m;
        return 0;
    }
    

    C 重力坠击

    数据范围很小, 爆搜

    struct node { int x, y, r; }e[N];
    
    void dfs(int now) {
        if(now == k) {
            memset(v, 0, sizeof(v));
            int res = 0;
            rep (i, 1, n) rep (j, 1, k)
                if (sqr(a[j] - e[i].x) + sqr(b[j] - e[i].y)
                    <= sqr(r + e[i].r) && v[i] == 0) ++res, v[i] = 1;
            umax(ans, res);
            return;
        }
        rep (i, -7, 7) rep (j, -7, 7) {
            a[now + 1] = i, b[now + 1] = j;
            dfs(now + 1);
        }
    }
    
    int main() {
        IOS; cin >> n >> k >> r;
        rep (i, 1, n) cin >> e[i].x >> e[i].y >> e[i].r;
        dfs(0);
        cout << ans << "
    ";
        return 0;
    }
    

    D Happy New Year!

    int main() {
        IOS; cin >> n;
        if (n < 2030) cout << 2030 + (n % 10 - 1);
        else cout << 2102;
        return 0;
    }
    

    E 买礼物

    最大值线段树, 维护出现上一个a[i]的位置的最大值

    struct BIT {
        struct node { int l, r, tag; } tr[N << 2];
        void push_up(int rt) { tr[rt].tag = max(tr[rt << 1].tag, tr[rt << 1 | 1].tag); }
        void build(int rt, int l, int r, int pre[]) {
            tr[rt] = { l, r, 0 };
            if (l == r) { tr[rt].tag = pre[l]; return; };
            int mid = l + r >> 1;
            build(rt << 1, l, mid, pre);
            build(rt << 1 | 1, mid + 1, r, pre);
            push_up(rt);
        }
        void change(int rt, int d, int k) {
            if (tr[rt].l == tr[rt].r && tr[rt].l == d) { tr[rt].tag = k; return; }
            int mid = tr[rt].l + tr[rt].r >> 1;
            if (d <= mid) change(rt << 1, d, k);
            if (d > mid) change(rt << 1 | 1, d, k);
            push_up(rt);
        }
        int ask(int rt, int l, int r) {
            if (tr[rt].l >= l && tr[rt].r <= r) return tr[rt].tag;
            int mid = tr[rt].l + tr[rt].r >> 1, ans = 0;
            if (l <= mid) umax(ans, ask(rt << 1, l, r));
            if (r > mid) umax(ans, ask(rt << 1 | 1, l, r));
            return ans;
        }
    } bit;
    
    int n, m, _, k;
    int h[M], ne[N], pre[N];
    
    int main() {
        IOS; cin >> n >> k;
        rep(i, 1, n) ne[i] = n + 1;
        rep(i, 1, n) cin >> m, ne[pre[i] = h[m]] = i, h[m] = i;
        bit.build(1, 1, n, pre);
        rep(i, 1, k) {
            int op, l, r; cin >> op >> l;
            if (op == 1) {
                bit.change(1, l, 0);
                if (pre[l]) ne[pre[l]] = ne[l];
                if (ne[l] != n + 1) bit.change(1, ne[l], pre[ne[l]] = pre[l]);
            }
            else {
                cin >> r;
                cout << (l <= bit.ask(1, l, r)) << '
    ';
            }
        }
        return 0;
    }
    

    F 匹配串

    答案明显要么无限要么为0

    正反个匹配一次即可, 记录每个串正着和倒着第一次出现'#' 的位置

    比如 a#cd#e, a#ef#e, 只要这两个串的正着和倒着到 '#'之前的字串匹配, 那就匹配, 中间的可以用#代替

    a#cd#e = aefcde, a#ed#e = aedcde, 当然这只是一种情况, 答案是无限

    int main() {
        IOS; cin >> n;
        rep (i, 1, n) cin >> s[i].s, umax(mx, s[i].s.size());
        rep (i, 1, n) {
            rep (j, 0, s[i].s.size() - 1) if (s[i].s[j] == '#') { s[i].p1 = j; break; }
            per (j, s[i].s.size() - 1, 0) if (s[i].s[j] == '#') { s[i].p2 = s[i].s.size() - 1 - j; break; }
        }
        sort(s + 1, s + n + 1, [](node &a, node &b) { return a.p1 < b.p1; });
        int nw = 1; bool f = 0;
        rep (i, 0, mx) {
            while (s[nw].s[i] == '#' && nw < n) ++nw;
            if (nw == n) break;
            char tmp = s[nw].s[i];
            rep (j, nw + 1, n) if (s[j].s[i] != tmp) { f = 1; break; }
        }
        sort(s + 1, s + n + 1, [](node &a, node &b) { return a.p2 < b.p2; });
        nw = 1;
        rep (i, 1, mx - 1) {
            while (s[nw].s[s[nw].s.size() - i] == '#' && nw < n) ++nw;
            if (nw == n) break;
            char tmp = s[nw].s[s[nw].s.size() - i];
            rep (j, nw + 1, n) if (s[j].s[s[j].s.size() - i] != tmp) { f = 1; break; }
        }
        cout << (f ? 0 : -1);
        return 0;
    }
    

    G 糖果

    权值并查集

    int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }
    
    void unit(int x, int y) { x = find(x); y = find(y); if (x != y) f[y] = x, umax(a[x], a[y]), sz[x] += sz[y]; }
    
    int main() {
        IOS; cin >> n >> m;
        rep (i, 1, n) cin >> a[i], f[i] = i, sz[i] = 1;
        rep (i, 1, m) {
            int u, v; cin >> u >> v;
            unit(u, v);
        }
        rep (i, 1, n) if (f[i] == i) ans += sz[i] * a[i];
        cout << ans;
        return 0;
    }
    

    H 数字串

    int main() {
        IOS; cin >> s; string t = ""; bool f = 0;
        for (int i = 0; s[i]; ++i)
            if (s[i] > 'j' && s[i] != 't') {
                rep (j, 0, i - 1) t += s[j];
                t += (s[i] - 'a' + 1) / 10 + 'a' - 1;
                t += (s[i] - 'a' + 1) % 10 + 'a' - 1;
                for (int j = i + 1; s[j]; ++j) t += s[j];
                f = 1; break;
            } else if (s[i + 1] && max(s[i], s[i + 1]) < 'j' && (s[i] - 'a' + 1) * 10 + (s[i + 1] - 'a' + 1) <= 26) {
                rep (j, 0, i - 1) t += s[i];
                t += (s[i] - 'a' + 1) * 10 + (s[i + 1] - 'a' + 1) + 'a' - 1;
                for (int j = i + 2; s[j]; ++j) t += s[j];
                f = 1; break;
            }
        if (f) cout << t;
        else cout << -1;
        return 0;
    }
    

    I 序列的美观度

    贪心, 在 (a[i] == a[j]) i~j 之间出现相同的数直接舍弃当前 i 即可

    int main() {
        IOS; cin >> n; unordered_set<int> st;
        rep (i, 1, n) {
            cin >> a[i];
            if (st.count(a[i])) ++m, unordered_set<int>().swap(st);
            st.insert(a[i]);
        }
        cout << m;
        return 0;
    }
    

    J 加法和乘法

    数据才 1e6, 直接模拟游戏比赛即可

    int main() {
        IOS; cin>>n; int ji = 0, ou = 0;
        rep (i ,1, n) cin >> m, ji += m % 2; ou = n - ji;
        while(ou + ji > 1) {
            if (ou >= 2) --ou;
            else if (ou >= 1 && ji >= 1) --ou;
            else if (ji >= 2) --ji;
            if (ji >= 2) ji -= 2, ++ou;
            else if (ji >= 1 && ou >= 1) --ji;
            else if(ou >= 2) --ou;
        }
        if (ou) cout << "NiuMei";
        else cout << "NiuNiu";
        return 0;
    }
    
  • 相关阅读:
    Asp.net技术点GridView+AspnetPager+Linq+ViewState 处理数据条件问题
    向本地添加jar包的经历
    elasticsearch 相关(ELK)
    elastaicsearch简单入门项目
    Zlibrary链接,全球最大的数字图书馆Zlibrary
    以短链服务为例,探讨免AppKey、免认证、Ajax跨域调用新浪微博API
    在线伪原创工具www.bolewei.com的开发过程
    如何用three.js(webgl)搭建3D粮仓、3D仓库、3D物联网设备监控第十二课
    如何用webgl(three.js)搭建处理3D隧道、3D桥梁、3D物联网设备、3D高速公路、三维隧道桥梁设备监控第十一课
    Windows、Ubuntu双系统 + 固态硬盘、机械硬盘通过Grub引导
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/14383543.html
Copyright © 2020-2023  润新知