Codeforces Round 890 (Div. 2) 赛后总结

小菜鸡的赛后总结


A. Tales of a Sort

  • 题意:给一个数组,可以执行一个操作:将所有数-1,最低减少到0,执行这个操作直到数组为递增,求出操作次数
  • 思路:找逆序对中最大的数即可,比较简单
void BlueFire()
{
    int n;
    cin >> n;
    vector<int> v(n + 1);
    int maxnn = 0;
    bool flag = 0;
    for (int i = 1; i <= n; i++)
    {
        cin >> v[i];
        if (v[i] < v[i - 1])
        {
            flag = 1;
            maxnn = max(v[i - 1], maxnn);
        }
    }
    if (!flag)
    {
        cout << 0 << endl;
        return;
    }
    else
    {
        cout << maxnn << endl;
    }
    return;
}

B. Good Arrays

  • 题意:给出一个a数组,求一个b数组,b数组满足两个条件:1.a数组和b数组相同下标的数不能相等。2.a数组的所有数之和与b数组的所有数之和相等。问这样的b数组是否存在(a和b的数都必须是正数)
  • 思路:观察样例思考,我们发现只需要在a数组上进行操作即可,既然需要和相等,又需要对应位置不是原来的数,那么可以想到,对于已经为1的数,为了让它变化并且和不变,就需要其他大于1的数分给它至少1,而大于1的数也可以分到直到其减少为1为止,当然,如果a数组里都大于1,也可以集中分到一个数上。所以只需要记录大于1的数以及等于1的数就行了。
void BlueFire()
{
    int n;
    cin >> n;
    vector<int> a(n + 1);
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    ll needF = 0;//需要分的
    ll needA = 0;//需要加的
    for (int i = 1; i <= n; i++)
    {
        if (a[i] > 1)
            needF += (a[i] - 1);
        else
            needA++;
    }
    if (needF >= needA && n != 1)
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
    return;
}

C. To Become Max

  • 题意:给出一个数组a,你可以对其进行一个操作:
    1.选择一个下标i,满足ai<=a(i+1)
    2.让ai + 1
    在进行最多k次操作后,找到数组a中可能的最大值
  • 思路:首先想到,对于一个正序对a[i],a[i+1],k充足的情况下a[i]最多能变为a[i+1],考虑顺序枚举,但是发现a[i]的变化可能会影响到其他逆序对,改变它们的性质。然后逆向思考,如果k充足的情况下a[i]能变为最大值x,那么a[i+1]一定是x-1,a[i+2]一定是x-2...所以可以二分答案,二分这个最大值,每次check枚举每个位置能否在k次内变为最大值。
int a[1010];
int n, k;
bool check(int mid)
{
    for (int i = 0; i < n; i++)
    {
        int t = k;
        int ans = mid;
        for (int j = i; j < n; j++)
        {
            if (a[j] >= ans)
                return true;
            if (t < ans - a[j])
                break;
            t -= ans - a[j];
            ans--;
        }
    }
    return false;
}
 
void BlueFire()
{
 
    cin >> n >> k;
    for (int i = 0; i < n; i++)
        cin >> a[i];
    int l = *max_element(a, a + n);
    int r = 1e9;
    while (l < r)
    {
        int mid = (l + r + 1) / 2;
        if (check(mid))
            l = mid;
        else
            r = mid - 1;
    }
    cout << l << endl;
    return;
}
posted @ 2023-08-08 15:17  布鲁诺邦古耐夫  阅读(62)  评论(0)    收藏  举报