Atcoder Beginner Contest 314

发布时间 2023-08-12 22:29:00作者: LittleDrinks

比赛情况

A 题直接按照题意用字符串输出就行了,很快切掉。

B 题按照题意模拟,但是各种 WA,吃了三发没过先去看 C。

C 题依然是模拟,这道题比较好写一次就过了,回去调 B。

B 题再吃了 3 发罚时终于过了。
先是没有特判输出 0 导致 vector 为空 WA/RE。
然后没有注意要从小到大输出,cmp 函数漏了一半对下标的判断。
最后是在找数字的时候,按照我的写法,如果全部符合条件,下标不会更新,此时答案为 0,寄。
总之,吃了 6 发罚时,总算是过了。

再开 D 题,一个离线忽略掉对整段序列的大小写修改,只保留最后一次即可。没想到也这么水,40 分钟切完 ABCD。

然后看 EF,一道期望 dp,一道分数取模,直接崩溃,痛骂出题人,摆了一会儿开 G。

G 题一开始想二分,然后想枚举,最后感觉枚举可行,只不过需要一个能在 \(O(\log n)\) 以内维护前 \(K\) 大所有数之和的东西。
不会,寄。

image
rating:571+33=604

赛时代码

A

#include <bits/stdc++.h>

using namespace std;

const int MAXN=1e5+5;
string s="1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679";
int n;

/*
*/

int main()
{
    cin.tie(nullptr) -> sync_with_stdio(false);

    // I.N.
    cin >> n;
    cout << "3.";
    for (int i = 0; i < n; ++i) { cout << s[i]; }

    // E.D.
    return 0;
}

B

#include <bits/stdc++.h>

using namespace std;

const int MAXN=105, MAXC=37;
int n, c[MAXN], x;
vector <int> num_to_p[MAXC];

/*
*/

bool cmp(int a, int b)
{
    return (
        (c[a] < c[b])
        || (c[a]==c[b] && a<b)
    );
}

int main()
{
    cin.tie(nullptr) -> sync_with_stdio(false);

    // I.N.
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> c[i];
        for (int j = 1; j <= c[i]; ++j) {
            int a; cin >> a;
            num_to_p[a].push_back(i);
        }
    }

    // 特判
    cin >> x;
    if (num_to_p[x].empty()) { cout << 0 << endl; return 0; }

    // 对中奖位置排序
    sort(num_to_p[x].begin(), num_to_p[x].end(), cmp);

    // 找到符合条件的人
    int sz = -1;
    for (int i = 1; i < num_to_p[x].size(); ++i) {
        if (c[num_to_p[x][i-1]] < c[num_to_p[x][i]]) {
            sz=i-1; break;
        }
    }
    sz = (sz==-1? num_to_p[x].size()-1: sz);

    // 输出
    cout << sz+1 << endl;
    for (int i = 0; i <= sz; ++i) {
        cout << num_to_p[x][i] << " ";
    }

    // E.D.
    return 0;
}

C

#include <bits/stdc++.h>

using namespace std;

const int MAXN=2e5+5;
int n, m;
char s[MAXN];
vector <int> color_to_idx[MAXN];

/*
*/

void operate(int c)
{
    int sz = color_to_idx[c].size();
    char temp = s[color_to_idx[c][sz-1]];
    for (int i = sz-1; i; --i) {
        s[color_to_idx[c][i]] = s[color_to_idx[c][i-1]];
    }
    s[color_to_idx[c][0]] = temp;
}

int main()
{
    cin.tie(nullptr) -> sync_with_stdio(false);

    // I.N.
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) {
        cin >> s[i];
    }
    for (int i = 1; i <= n; ++i) {
        int c; cin >> c;
        color_to_idx[c].push_back(i);
    }

    // 模拟位置变化
    for (int i = 1; i <= m; ++i) { operate(i); }

    // 输出
    for (int i = 1; i <= n; ++i) {
        cout << s[i];
    }

    // E.D.
    return 0;
}

D

#include <bits/stdc++.h>

using namespace std;

const int MAXN=5e5+5;
int n, q, status;
char s[MAXN];

/*
*/

char upper_to_lower(char x)
{
    if ( ('a' <= x) && (x <= 'z') ) { return x; }
    return char(x+'a'-'A');
}

char lower_to_upper(char x)
{
    if ( ('A' <= x) && (x <= 'Z') ) { return x; }
    return char(x-'a'+'A');
}

struct OP {
    int t, x;
    char c;
} p[MAXN];

void modify(int t)
{
    for (int i = 1; i <= n; ++i) {
        s[i] = (t==2? upper_to_lower(s[i]): lower_to_upper(s[i]));
    }
}

int main()
{
    cin.tie(nullptr) -> sync_with_stdio(false);

    // I.N.
    cin >> n;
    for (int i = 1; i <= n; ++i) { cin >> s[i]; }

    // 离线,找到最后一次修改大小写,前面全都不用改
    cin >> q;
    int last_mdf_all = q+1;
    for (int i = 1; i <= q; ++i) {
        cin >> p[i].t >> p[i].x >> p[i].c;
        if (p[i].t != 1) { last_mdf_all = i; }
    }

    // 做修改
    for (int i = 1; i <= q; ++i) {
        if (p[i].t == 1) {
            s[ p[i].x ] = p[i].c;
        } else if (i == last_mdf_all) {
            modify(p[i].t);
        }
    }

    // 输出
    for (int i = 1; i <= n; ++i) {
        cout << s[i];
    }

    // E.D.
    return 0;
}