Codeforces Round #713 (Div. 3)

昨天下午监考招新赛时做的 =。= 话说前天晚上验题时还想着这么简单肯定会有人 ak 来着,结果第一过题数也才 9/12 。

比赛链接:https://codeforces.com/contest/1512

A. Spy Detected!

题解一

记录每个值所在的下标,之后遍历一遍找到只有一个下标的值。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--) {
        int n;
        cin >> n;
        vector<vector<int>> pos(105);
        for (int i = 0; i < n; i++) {
            int x;
            cin >> x;
            pos[x].push_back(i);
        }
        for (auto vec : pos) {
            if (vec.size() == 1) {
                cout << vec.back() + 1 << "\n";
            }
        }
    }
    return 0;
}

题解二

因为数组中只有两个值,不论只出现了一次的值是大是小,排序后一定是在首尾之一,所以排序后在数组中第二个位置的值一定为多次出现的值。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--) {
        int n;
        cin >> n;
        vector<int> a(n);
        for (int i = 0; i < n; i++) {
            cin >> a[i];
        }
        vector<int> b(a);
        sort(b.begin(), b.end());
        for (int i = 0; i < n; i++) {
            if (a[i] != b[1]) {
                cout << i << "\n";
            }
        }
    }
    return 0;
}

B. Almost Rectangle

题解

记录 * 所在的横纵坐标,之后 \(2 \times 2\) 组合即可。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--) {
        int n;
        cin >> n;
        vector<string> MP(n);
        set<int> x, y;
        for (int i = 0; i < n; i++) {
            cin >> MP[i];
            for (int j = 0; j < n; j++) {
                if (MP[i][j] == '*') {
                    x.insert(i);
                    y.insert(j);
                }
            }
        }
        auto to_two = [&](set<int>& st) {
            if (st.size() == 1) {
                if (*st.begin() + 1 < n) {
                    st.insert(*st.begin() + 1);
                } else {
                    st.insert(*st.begin() - 1);
                }
            }
        };
        to_two(x), to_two(y);
        for (auto i : x) {
            for (auto j : y) {
                MP[i][j] = '*';
            }
        }
        for (int i = 0; i < n; i++) {
            cout << MP[i] << "\n";
        }
    }
    return 0;
}

C. A-B Palindrome

题解

先处理字符串中必须替换的字符,即一方为 ? 一方为 0 或 1 的情况,之后将成对的 ? 替换即可。

Tips

成对替换时如果是奇回文串的中心部分只要一个 0 或 1 就可以了。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--) {
        int a, b;
        cin >> a >> b;
        string s;
        cin >> s;
        int n = a + b;
        a -= count(s.begin(), s.end(), '0');
        b -= count(s.begin(), s.end(), '1');
        for (int i = 0; i < n; i++) {
            if (s[i] != '?' and s[n - 1 - i] == '?') {
                if (s[i] == '0' and a > 0) {
                    s[n - 1 - i] = s[i];
                    --a;
                } else if (s[i] == '1' and b > 0) {
                    s[n - 1 - i] = s[i];
                    --b;
                }
            }
        }
        for (int i = 0; i < n; i++) {
            if (s[i] == '?' and s[n - 1 - i] == '?') {
                int sub = 1 + (i != n - 1 - i);
                if (a >= sub) {
                    s[i] = s[n - 1 - i] = '0';
                    a -= sub;
                } else if (b >= sub) {
                    s[i] = s[n - 1 - i] = '1';
                    b -= sub;
                }
            }
        }
        if (max(a, b) == 0 and s == string(s.rbegin(), s.rend())) {
            cout << s << "\n";
        } else {
            cout << -1 << "\n";
        }
    }
    return 0;
}

D. Corrupted Array

题解

\(\sum_{i = 1}^{n + 2} \limits b_i = 2b_{n + 1} + x\) ,枚举 \(x\) ,判断 \(b\) 中是否存在相应的 \(b_{n + 1}\) ,如果存在,去除 \(x\)\(b_{n + 1}\) 即可。

Tips

本题官方题解有一点与题目矛盾,就是必须加上 \(2b_{n+1} = (\sum_{i = 1}^{n + 2} \limits b_i) - x \le 2 \times 10^9\) 的判断条件,因为按照题目输入中的限制, \(b_i \le 10^9\) ,所以即使 \((\sum_{i = 1}^{n + 2} \limits b_i) - x > 2 \times 10^9\) ,也不会存在相应大小的 \(b_{n + 1}\)

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--) {
        int n;
        cin >> n;
        vector<int> b(n + 2);
        long long sum = 0;
        for (int i = 0; i < n + 2; i++) {
            cin >> b[i];
            sum += b[i];
        }
        multiset<int> mst(b.begin(), b.end());
        for (int i = 0; i < n + 2; i++) {
            int x = b[i];
            if ((sum - x) <= 2'000'000'000 and (sum - x) % 2 == 0 and (x == (sum - x) / 2 ? mst.count(x) >= 2 : mst.count((sum - x) / 2))) {
                mst.erase(mst.find(x));
                mst.erase(mst.find((sum - x) / 2));
                for (auto val : mst) {
                    cout << val << ' ';
                }
                cout << "\n";
                break;
            } else if (i == n + 1) {
                cout << -1 << "\n";
            }
        }
    }
    return 0;
}

E. Permutation by Sum

题解

先以 \(1,\ 2\ ...\ \ r - l + 1\) 填充 \(p_l,\ p_{l+1}\ ...\ p_r\) ,之后为每个数加上 \(\lfloor \frac{s - \sum_{i = l}^{r} \limits p_i}{len} \rfloor\) ,如果还有余数,因为区间中的数是连续的,所以需要从右端点往左加。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--) {
        int n, l, r, s;
        cin >> n >> l >> r >> s;
        --l, --r;
        int seg_len = r - l + 1;
        vector<int> p(seg_len);
        iota(p.begin(), p.end(), 1);
        int sum = (1 + seg_len) * seg_len / 2;
        int extra_need = max(0, s - sum) / seg_len;
        for (int i = 0; i < seg_len; i++) {
            p[i] += extra_need;
        }
        for (int i = 0; i < (s - sum - extra_need * seg_len); i++) {
            ++p[seg_len - 1 - i];
        }
        if (sum > s or p.back() > n) {
            cout << -1 << "\n";
        } else {
            set<int> st;
            for (int i = 1; i <= n; i++) {
                st.insert(i);
            }
            vector<int> ans(n);
            for (int i = l; i <= r; i++) {
                ans[i] = p[i - l];
                st.erase(ans[i]);
            }
            for (int i = 0; i < n; i++) {
                if (ans[i] == 0) {
                    ans[i] = *st.begin();
                    st.erase(st.begin());
                }
            }
            for (int i = 0; i < n; i++) {
                cout << ans[i] << " \n"[i == n - 1];
            }
        }
    }
    return 0;
}

F. Education

题解

枚举以每个职位为终点挣够 \(c\) 所需的天数即可。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    #define int long long
    int t;
    cin >> t;
    while (t--) {
        int n, c;
        cin >> n >> c;
        vector<int> a(n);
        for (int i = 0; i < n; i++) {
            cin >> a[i];
        }
        vector<int> b(n - 1);
        for (int i = 0; i < n - 1; i++) {
            cin >> b[i];
        }
        int ans = INT_MAX;
        int now = 0, days = 0;
        for (int i = 0; i < n; i++) {
            if (now >= c) {
                ans = min(ans, days);
            } else {
                ans = min(ans, days + (c - now + a[i] - 1) / a[i]);
            }
            if (i < n - 1) {
                if (now >= b[i]) {
                    now -= b[i];
                    ++days;
                } else {
                    int day = (b[i] - now + a[i] - 1) / a[i];
                    now += day * a[i] - b[i];
                    days += day + 1;                    
                }
            }
        }
        cout << ans << "\n";
    }
    return 0;
}

G. Short Task

题解

埃筛一遍即可。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    const int N = 1e7 + 10;
    vector<int> d(N), ans(N, -1);
    for (int i = 1; i < N; i++) {
        for (int j = i; j < N; j += i) {
            d[j] += i;
        }
    }
    for (int i = 1; i < N; i++) {
        if (d[i] < N and ans[d[i]] == -1) {
            ans[d[i]] = i;
        }
    }
    int t;
    cin >> t;
    while (t--) {
        int c;
        cin >> c;
        cout << ans[c] << "\n";
    }
    return 0;
}
posted @ 2021-04-12 17:20  Kanoon  阅读(59)  评论(0编辑  收藏  举报