Codeforces Round 870 (Div.2) A~C

发布时间 2023-07-04 19:25:32作者: wuyoudexian

vp时A题没写出来,场外找的答案,原来思路错了(心虚

A. Trust Nobody

Problem - A - Codeforces

题意

有n个人,其中一些人只说真话,另外一些人只说谎话。每人会说在我们之中至少有x人是说谎者,求说谎者的人数。若所有人的说法矛盾,则输出-1。

思路

枚举答案然后验证即可,若无答案,输出-1。

代码

void solve() {
    int n;
    cin >> n;
 
    vector<int> v(n);
    for(int i = 0; i < n; i++) {
        cin >> v[i];
    }
 
    for(int i = 0; i <= n; i++) {
        int cnt = 0;
        for(int j = 0; j < n; j++) {
            cnt += i < v[i];
        }
        if(cnt == i) {
            cout << i << "\n";
            return;
        }
    }
    
    cout << -1 << "\n";
}

B. Lunatic Never Content

Problem - B - Codeforces

题意

给定一个长为n的序列a,定义f(a, x) = [a1 mod x, a2 mod x,..., an mod x],x是一个正整数。求x的最大值,使得f(a, x)为一个回文序列。

思路

如果要使a,b两个数模x后相等,那么x只能为两个数的差值的所有因数。所以,要使得f(a, x)为回文序列,即模所有左右对称的数的差值的最大公因数。

代码

void solve() {
    int n;
    cin >> n;

    vector<int> v(n);
    for(int i = 0; i < n; i++) {
        cin >> v[i];
    }

    int ans = 0;
    for(int i = 0; i < n / 2; i++) {
        ans = gcd(ans, abs(v[i] - v[n-i-1]));
    }

    cout << ans << "\n";
}

C. Dreaming of Freedom

Problem - C - Codeforces

题意

给定n个人和m个选项,让n个人选择,被选择数最多的选项留下来。如果有多个选项留下来,再让n个人选择,直至最后只剩一个选项。如果无论怎么选择最后都会只剩下一个选项,则输出"YES",否则输出"NO"。

思路

只要确定有n个人可划分为个若干个群体,每个群体的人数相同,并且群体的数量不大于m,则输出"NO",否则输出"YES"。

枚举每个群体的人数进行验证,枚举范围从1到\(\sqrt n\),每次枚举的群体的数量为 n/i 和 n/n/i。当 n=1 或 m=1 时,注意特判。

代码

void solve() {
    int n, m;
    cin >> n >> m;
 
    if(n == 1 || m == 1) {
        cout << "YES\n";
        return;
    }
 
    for(int i = 1; i * i <= n; i++) {
        if(n % i != 0) {
            continue;
        }
        if(n / i <= m || (i <= m && i != 1)) {
            cout << "NO\n";
            return;
        }
    }
 
    cout << "YES\n";
}

D. Running Miles

Problem - D - Codeforces

题意

给定一个序列,找一个区间,要求区间内最大的三个值之和减去区间的长度最大。求这个最大值。

思路

设dp[i]为选了i个元素的最大值。则状态转移方程为dp[j]=max(dp[j], dp[j-1]+v[i]),并且每次枚举i的加一时,当前的dp[1]和dp[2]要减一,表示区间增长。

代码

void solve() {
    int n;
    cin >> n;
 
    vector<int> v(n);
    for(int i = 0; i < n; i++) {
        cin >> v[i];
    }
 
    array<int, 4> dp{0};
    for(int i = 0; i < n; i++) {
        dp[1] -= 1;
        dp[2] -= 1;
        for(int j = 3; j; j--) {
            dp[j] = max(dp[j], dp[j-1] + v[i]);
        }
    }
 
    cout << dp[3] << "\n";
}