AtCoder Beginner Contest 097

目录

A - Colorful Transceivers

给出abcd四个数,abc都是一维坐标,问a能否和c直接或间接联通,坐标差值在d以内的可以直接联通

直接模拟即可

#include<bits/stdc++.h>

using namespace std;

const int N = 1e6 + 5;
typedef long long LL;
int a, b, c, d;
int main(){
    cin >> a >> b >> c >> d;
    if (abs(a - c) <= d) cout << "Yes" << endl;
    else if(abs(a-b)<=d&&abs(b-c)<=d)
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
    return 0;
}

B - Exponential

给出n,要求输出小于等于n的最大完美数,完美数的定义是可以表示为某个数的p次方的形式,其中p大于等于2

直接打表即可

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 5;
typedef long long LL;
int n, a[N],cnt;
int main() {
    a[cnt++] = 1;
    for (int i = 2; i <= sqrt(1000); i++) {
        for (int j = 2; pow(i, j) <= 1000; j++) {
            a[cnt++] = pow(i, j);
        }
    }
    sort(a, a + cnt);
    cnt = unique(a, a + cnt) - a;
    cin >> n;
    cout << a[upper_bound(a, a + cnt, n) - a - 1 ]<< endl;
    return 0;
}

C - K-th Substring

给出一个字符串s,问在s的不同子串中,字典序第k大的子串是什么

首先可以想到n方的算法,枚举起点和字符串长度即可,但是这样只能过200分,因为s长度为2e4,会超时

但是因为k小于5,所以对于每个起点,只需要取前k个子串即可,这样复杂度降为kn

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 5;
typedef long long LL;
set<string> st;
string s;
int k;
int main() {
    cin >> s;
    cin >> k;
    for (int i = 0; i < s.size(); i++) {
        string tmp = "";
        for (int j = 0; j < min((int)s.size() - i,k); j++) {
            tmp.push_back(s[j + i]);
            st.insert(tmp);
        }
    }
    int cnt = 0;
    for (auto i : st) {
        cnt++;
        if (cnt == k) {
            cout << i << endl;
            break;
        }
    }
    return 0;
}

D - Equals

给出一个数组p,长度为n,现在有m个交换方法,可以将\(p_{m_{i1}}\)和\(p_{m_{i2}}\)交换,问经过任意次交换,最后满足\(p_i=i\)的元素最多有多少

经过手推+猜结论,可以得到:

如果一个位置可以经过多个不同的交换和另一个位置交换,那么可以视为直接将这两个位置交换,而不影响别的位置

那么可以想到利用并查集,看\(p_i\)和i是否在一个集合里即可

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 5;
typedef long long LL;
int n, m, a[N], add[N], f[N];
int findf(int x) { return x == f[x] ? x : f[x] = findf(f[x]); }
void Union(int x, int y) {
    int fx = findf(x), fy = findf(y);
    if (fx != fy) f[fx] = fy;
}
int main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        add[a[i]] = i;
        f[i] = i;
    }
    for (int i = 0; i < m; i++) {
        int x, y;
        cin >> x >> y;
        Union(x, y);
    }
    int res = 0;
    for (int i = 1; i <= n; i++) {
        if (a[i] == i) {
            res++;
        } else {
            int fx = findf(i), fy = findf(add[i]);
            if (fx == fy) res++;
        }
    }
    cout << res << endl;
    return 0;
}
上一篇:【AtCoder Beginner Contest Round #181】题解


下一篇:AtCoder Beginner Contest 182 F - Valid payments