Educational Codeforces Round 14

Educational Codeforces Round 14

https://codeforces.com/contest/691
4/6:ABCD (C是恶心人的模拟分类讨论,写了巨久导致没时间看EF)

这场没有红题,应该是可以补完的。

A. Fashion in Berland

注意读题!!特判只有一个的时候!!

#include <bits/stdc++.h>

using namespace std;

int main () {
    int n, ans = 0;
    cin >> n;
    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        if (x == 0) ans ++;
    }
    if (n == 1) {
        if (!ans) cout << "YES";
        else    cout << "NO";
        return 0;
    }
    if (ans == 1)  cout << "YES";
    else    cout << "NO";
}

B. s-palindrome

考察眼神的题
m和自己不对称, 逆天

#include <bits/stdc++.h>

using namespace std;
set<char> se = {'A', 'H', 'I', 'M', 'O', 'o', 'T', 'U', 'V', 'v', 'W', 'w', 'X', 'x', 'Y'};
map<char, char> mp;

int main () {
    string s;
    cin >> s;
    mp['b'] = 'd', mp['d'] = 'b', mp['p'] = 'q', mp['q'] = 'p';
    int n = s.size ();
    for (int i = 0; i <= n / 2; i++) {
        if (se.count (s[i])) {
            if (s[n-i-1] != s[i]) {
                cout << "NIE";
                return 0;
            }
        }
        else {
            if (s[n-i-1] == mp[s[i]])   continue;
            cout << "NIE";
            return 0;    
        }
    }
    cout << "TAK";
}

//可以和自己对称: A, H, I, M, O, o, T, U, V, v, W, w, X, x, Y
//组成一队的: {b,d}, {p,q}
//m和自己不对称, 逆天

C. Exponential notation

写了巨久的分类讨论,嗨多细节(也可能是我太菜了)
不过所幸赶在结束之前1A了该题,感觉得益于边写边给自己多捏了好几个样例。
具体细节看代码注释,已经分好类了。
应该算写的比较清楚吧qaq如果有更好的写法再学习学习。

#include <bits/stdc++.h>

using namespace std;

void print (string s, bool isPos) {
    if (isPos) { //打印整数部分
        if (s.size () == 1) {
            cout << s;
            return ;
        }
        cout << s[0];
        int ed;
        if (count (s.begin (), s.end (), '0') < s.size () - 1) {
            cout << '.';
            for (int i = s.size () - 1; i >= 0; i--) {
                if (s[i] != '0') {
                    ed = i;
                    break;
                }
            }
            for (int i = 1; i <= ed; i++)    cout << s[i]; 
        }
        cout << "E" << s.size () - 1;
    }
    else { //打印小数部分
        int st;
        for (int i = 0; i < s.size (); i++) {
            if (s[i] != '0') {
                st = i;
                break;
            }
        }
        cout << s[st];
        if (st != s.size() - 1) {
            cout << '.';
            for (int i = st + 1; i < s.size (); i++)    cout << s[i];
        }
        cout << "E-" << st + 1;
    }
}

int main () {
    string t, s;
    cin >> t;
    int st = 0, ed = t.size () - 1;
    if (!count (t.begin (), t.end (), '.')) { //没有点
        for (int i = 0; i < t.size (); i++) {
            if (t[i] != '0') {
                st = i;
                break;
            }
        }
        s = t.substr (st, ed - st + 1);  //去除多余0
        print (s, true);
    }
    else {  //有点
        for (int i = 0; i < t.size (); i++) {
            if (t[i] != '0' || t[i] == '.') {
                st = i;
                break;
            }
        }
        for (int i = t.size () - 1; i >= 0; i--) {
            if (t[i] != '0') {
                ed = i;
                break;
            }
        }
        s = t.substr (st, ed - st + 1);
        int n = s.size();
        if (s == ".") {
            cout << 0;
            return 0;
        }
        if (s[n - 1] == '.') { //没有小数部分
            s = s.substr (0, n - 1);
            //cout << s << endl;
            print (s, true);
            return 0;
        }
        if (s[0] == '.') { //没有整数部分
            s = s.substr (1, n - 1);
            print (s, false);
            return 0;
        }
        if (s[1] == '.') { //0次方
            cout << s << endl;
            return 0;
        }
        //xx.xxx
        //cout << s;

        cout << s[0] << '.';
        int pos;
        for (int i = 0; i < s.size (); i++) {
            if (s[i] == '.') {
                pos = i;
                break;
            }
        }
        for (int i = 1; i < s.size (); i++) {
            if (i != pos)   cout << s[i];
        }
        cout << "E" << pos - 1;
    }
}

//先去掉前置和后缀0

D. Swaps in Permutation

并查集 + 堆
小贪心。
把能互换的几个数字塞进一个堆里面,然后贪心先放最大的即可。
注意审清楚题目,给的是位置而不是数值(一开始就因为这里理解错而WA了一发)

#include <bits/stdc++.h>

using namespace std;
const int N = 1e6 + 5;
priority_queue<int> q[N];
int n, m, fa[N], a[N];

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

int main () {
    cin >> n >> m;
    for (int i = 1; i <= n; i++)    cin >> a[i], fa[i] = i;
    while (m --) {
        int x, y;
        cin >> x >> y; //给的是位置
        x = find (a[x]), y = find (a[y]);
        if (x != y)     fa[x] = y;
    }
    for (int i = 1; i <= n; i++)    q[find (a[i])].push (a[i]);
    for (int i = 1; i <= n; i++) {
        int id = find (a[i]);
        //cout << id << ' ';
        cout << q[id].top () << ' ';
        q[id].pop ();
    }
}

//贪心 + 堆维护

E. Xor-sequences

矩阵快速幂优化dp。
一些矩阵快速幂的blog:
从零开始的矩阵乘法
矩阵加速图上问题学习笔记
等我写篇原理。

F. Couple Cover

posted @ 2023-01-08 11:30  Sakana~  阅读(36)  评论(0编辑  收藏  举报