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

                
            
浙公网安备 33010602011771号