AtCoder Beginner Contest 131

AtCoder Beginner Contest 131

https://atcoder.jp/contests/abc131
4/6:ABCD

A - Security

水题

#include <bits/stdc++.h>

using namespace std;

signed main () {
    string s;
    cin >> s;
    for (int i = 1; i < 4; i++) {
        if (s[i] == s[i-1]) {
            cout << "Bad";
            return 0;
        }
    }
    cout << "Good";
}

B - Bite Eating

找出绝对值最小的 \(L+i-1\)

#include <bits/stdc++.h>

using namespace std;

signed main () {
    int n, L;
    cin >> n >> L;
    int dx = -1;
    if (L >= 0)     dx = L;
    else {
        if (n - 1 >= -L)    dx = 0;
        else    dx = L + n - 1;
    }
    cout << n * L - n + n * (n + 1) / 2 - dx;
}

C - Anti-Division

简单数论(?)。
查询[a,b]里面有多少c,d的倍数,直接除, \(O(1)\) 查询,记得容斥掉二者共同的倍数。

#include <bits/stdc++.h>
#define int long long

using namespace std;
int a, b, c, d;

int count (int x) {
    return b / x - (a + x - 1) / x + 1;
}

signed main () {
    cin >> a >> b >> c >> d;
    int lcm = (c * d) / __gcd (c, d);
    //cout << count (c) << ' ' << count (d) << ' ' << count (lcm) << endl;
    cout << b - a + 1 - (count (c) + count (d) - count (lcm)) << endl;
}

//查询[a,b]里面有多少c,d的倍数

D - Megalomania

模拟题。先排序后直接模拟

#include <bits/stdc++.h>
#define int long long

using namespace std;
typedef pair<int, int> pii;
const int N = 2e5 + 5;
pii p[N];
int n;

signed main () {
    cin >> n;
    for (int i = 1; i <= n; i++)    cin >> p[i].second >> p[i].first;
    sort (p + 1, p + n + 1);
    int dx = 0;
    for (int i = 1; i <= n; i++) {
        dx += p[i].second;
        //cout << dx << ' ';
        if (dx > p[i].first) {
            puts ("No");
            return 0;
        }
    }
    puts ("Yes");
}

//查询[a,b]里面有多少c,d的倍数

E - Friendships

构造题。
完全图:\(0\) 个;
最多的情况:以一个点为中心的菊花图,共 $\frac{(n-1)\times(n-2)}{2} $ 对点。
如何构造在此范围内的边:画几个图不难发现,完全图中每去掉一条边就会多一对符合条件的点。故边数为 \(\frac{n\times (n-1)}{2}-k\)

#include <bits/stdc++.h>

using namespace std;

int main () {
    int n, m;
    cin >> n >> m;
    if (m > (n - 2) * (n - 1) / 2)      cout << -1;
    else {
        int cnt = n * (n - 1) / 2 - m;
        cout << cnt << endl;
        for (int i = 1; i < n; i++) {
            for (int j = i + 1; j <= n; j++) {
                cout << i << ' ' << j << endl;
                cnt --;
                if (cnt == 0)       return 0;
            }
        }
    }
}

//最多的时候是以一个点为中转,则有 (n-1)*(n-2)/2个  

F - Must Be Rectangular!

数据结构。
很难想到是一道冰茶几。
怎么判断某点是哪一个矩形?利用并查集的归属关系。

#include <bits/stdc++.h>
#define ll long long

using namespace std;
const int N = 1e5 + 5, M = N * 2;
int fa[M], hang[M], lie[M], n;
ll ans;

int find (int x) {
    if (x != fa[x])     fa[x] = find (fa[x]);
    return fa[x];
}

int main () {
    for (int i = 1; i < M; i++)    fa[i] = i;
    cin >> n;
    for (int i = 0; i < n; i++) {
        int x, y;
        cin >> x >> y;
        x =  find (x), y = find (y + N);
        if (x != y)     fa[x] = y;
    }
    for (int i = 1; i < N; i++)     hang[find(i)] ++, lie[find (i + N)] ++;
    for (int i = 1; i < M; i++)     ans += 1ll * hang[i] * lie[i];
    cout << ans - n << endl;
}

//dsu
posted @ 2023-01-04 16:24  Sakana~  阅读(25)  评论(0编辑  收藏  举报