Codeforces Round #579 (Div. 3)

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

A - Circle of Students

题意

$n$ 个数的一种排列组成一个环,问能否顺时针或逆时针可以从 $1$ 依次走到 $n$ 。

题解一

记录 $1$ 的位置,从该位置出发顺、逆时针各走 $n-1$ 次,看是否有一次满足题意。

代码一

#include <bits/stdc++.h>
using namespace std;

void solve() {
    int n; cin >> n;
    int a[n] = {};
    int pos = -1;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        if (a[i] == 1) {
            pos = i;
        }
    }
    bool okl = true, okr = true;
    for (int i = 1; i < n; i++) {
        okl &= (a[(pos - i + n) % n] == i + 1);
        okr &= (a[(pos + i + n) % n] == i + 1);
    }
    cout << (okl or okr ? "YES" : "NO") << "\n";
}

int main() {
    int t; cin >> t;
    while (t--) solve();
}

题解二

根据前两个元素的大小判断应为递增序还是递减序。

代码二

#include <bits/stdc++.h>
#define nx(x) (x + 1) % n
#define pre(x) (x - 1 + n) % n
using namespace std;

void solve() {
    int n; cin >> n;
    int a[n] = {};
    for (int i = 0; i < n; i++) cin >> a[i], --a[i];
    if (n == 1) {
        cout << "YES\n";
        return;
    }
    if (a[1] == (a[0] + 1) % n) {
        for (int i = 0; i < n; i++) {
            if (a[i] != (a[pre(i)] + 1) % n) {
                cout << "NO\n";
                return;
            }
        }
        cout << "YES\n";
    } 
    else {
        for (int i = 0; i < n; i++) {
            if (a[i] != (a[pre(i)] - 1 + n) % n) {
                cout << "NO\n";
                return;
            }
        }
        cout << "YES\n";
    }
}

int main() {
    int t; cin >> t;
    while (t--) solve();
}

B - Equal Rectangles

题意

有 $4n$ 条边,问这些边能否组成 $n$ 个相同的矩形。

题解

先把边按大小排序,然后每次从两端各取两边,先判断同一端的两边是否相等,然后判断它们的面积是否为定值。

代码

#include <bits/stdc++.h>
using namespace std;

void solve() {
    int n; cin >> n;
    int a[4 * n] = {};
    for (auto &i : a) 
        cin >> i;
    sort(a, a + 4 * n);
    int area = a[0] * a[4 * n - 1];
    bool ok = true;
    for (int i = 0; i < n; i++) {
        int l = 2 * i, r = 4 * n - 1 - 2 * i;
        if (a[l] != a[l + 1] or a[r] != a[r - 1] or a[l] * a[r] != area)
            ok = false;
    }
    cout << (ok ? "YES" : "NO") << "\n";
}

int main() {
    int t; cin >> t;
    while (t--) solve();
}

C - Common Divisors

题意

找出 $n$ 个数有多少个共同因子。

题解

求 $n$ 个数 $gcd$ 的因子个数即可。

代码

#include <bits/stdc++.h>
using LL = long long;
using namespace std;
int main() {
    int n; cin >> n;
    LL gcd = 0;
    for (int i = 0; i < n; i++) {
        LL x; cin >> x;
        gcd = __gcd(x, gcd);
    }
    int ans = 0;
    for (LL i = 1; i * i <= gcd; i++) {
        if (gcd % i == 0) 
            ans += (i * i == gcd ? 1 : 2);
    }
    cout << ans;
}

D2. Remove the Substring (hard version)

题意

给定字符串 $s$ 和 $t$,$t$ 为 $s$ 的一个子序列,要求从 $s$ 中移除一个连续子串后 $t$ 仍为余下字符串的子序列,问可移除连续子串的最大长度。

题解

待填。

E - Boxers

题意

有 $n$ 个正整数,每个数改变前后之差的绝对值至多为 $1$,不可以减为 $0$,问这 $n$ 个数最多能有多少个不同的数。

题解

贪心,和 CF1283E 类似。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    int n; cin >> n;
    int a[n] = {};
    for (auto &i : a)
        cin >> i;
    sort(a, a + n);
    map<int, bool> vis;
    vis[0] = true;
    for (int i = 0; i < n; i++) {
        if (!vis[a[i] - 1]) 
            a[i] = a[i] - 1;
        else if (!vis[a[i]])
            a[i] = a[i];
        else if (!vis[a[i] + 1])
            a[i] = a[i] + 1;
        vis[a[i]] = true;
    }
    cout << vis.size() - 1 << "\n";
}

 

posted @ 2020-05-05 23:00  Kanoon  阅读(137)  评论(0)    收藏  举报