ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2021-02-06 23:33:51  阅读:163  来源: 互联网

标签:int rep cin st 牛客 2021 ou 集训营 nw


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\n"; 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 << '\n';
    }
    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 << "\n";
    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)) << '\n';
        }
    }
    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;
}

标签:int,rep,cin,st,牛客,2021,ou,集训营,nw
来源: https://www.cnblogs.com/2aptx4869/p/14383543.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有