Codeforces Round 1045 (Div. 2) (A ~ C)

A. Painting With Two Colors

思维

题意:

一个长度为\(n\)的数组,先把一段长度为\(a\)的子数组染为红色,再把一段长度为\(b\)的子数组染为蓝色,蓝色会覆盖红色。求能不能使得数组是回文。

思路:

最后要求数组是回文的那么每次都需要对称的去放,分成以下两种情况判断一下即可:

  • \(a\)\(b\)\(n\)奇偶性都相同
  • \(a\)\(n\)奇偶性不同,这时需要用蓝色去覆盖使其对称,所以\(b\) > \(a\)并且\(b\)\(n\)奇偶性相同

不满足以上情况之一的都是不对称的

代码:

void solve()
{
    int n, a, b;
    std::cin >> n >> a >> b;
    if (b % 2 == n % 2 and (b > a or a % 2 == n % 2)) std::cout << "YES\n";
    else std::cout << "NO\n";
}

B. Add 0 or K

数论

题意:

给定一个数组以及一个\(k\),最多可以对数组做不超过\(k\)次操作,每次操作可以给数组每个数加上\(0\)或者\(k\),要求通过若干次操作使数组的\(gcd\) > \(1\),输出这个数组

思路:

首先定义这样的一个数组\(gcd\) = \(p\),它符合\(gcd(p, k) = 1\)
可以证明在\(k\)次操作以内通过对数组元素若干次加\(k\),使其可以被\(p\)整除
证明:

如何找到这样的\(p\)

代码:

void solve()
{
    int n, k, p = 2;
    cin >> n >> k;
    while(__gcd(p,k) > 1) p ++;
    for(int i = 1; i <= n; i ++)
    {
        int x;
        cin >> x;
        while(x % p > 0) x += k;
        cout << x << " \n"[i == n]; 
    }
}

C. Even Larger

贪心 思维

题意:

给定一个数组,每次操作可以将一个数组元素的值减一,问最少需要多少次操作可以使所有长度大于等于\(2\)的子数组满足偶数索引元素之和 >= 奇数索引元素之和(这里索引的奇偶是相对原数组来说的)

思路:

不难发现让\(a_i >= a_{i - 1} + a_{i + 1}\)即可,这里的\(i\)都是偶数索引,如果某一索引不符合条件的话优先减小\(a_{i + 1}\)的值,这样对后面的元素可能也是有贡献的

代码:

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

    vector<int> a(n + 1);
    for(int i = 1; i <= n; i ++) cin >> a[i];

    int cnt = 0;
    for(int i = 2; i <= n; i += 2)
    {
        int x = a[i - 1];
        if(i + 1 <= n) x += a[i + 1];

        int t = max(x - a[i], 0LL);
        cnt += t;

        if(i + 1 <= n) a[i + 1] -= min(t, a[i + 1]);
    }

    cout << cnt << '\n';
}
posted @ 2025-08-27 15:12  Gabriel_7  阅读(23)  评论(0)    收藏  举报