返回顶部

Codeforces Round 906 (Div. 2)

A. Doremy's Paint 3

思路:分析可知数组最多有两种数字

两种情况:

  1. 当数组只有一种数字时,任意排列都可以。
  2. 当数组有两个数字时,交错排列,每种数字数目差值要小于等于1.

code:

int n;
void solved()
{
    cin >> n;
    int num = 0;     // 数字种类数
    vector<int> b;
    int a[N]={0};
    for (int i = 1; i <= n; ++i)
    {
        int tot;
        cin >> tot;
        if (a[tot] == 0)
        {
            num++;
            b.push_back(tot);
        }
        a[tot]++;
    }
    if (num == 1 || (num == 2 && abs(a[b[0]] - a[b[1]]) < 2))
    {
        cout << "YES" << endl;
    }
    else
    {
        cout << "NO" << endl;
    }
}

B. Qingshan Loves Strings

思路:s串不能同时11和00的子串,t的首尾必须相同并且与s串中的连续相同子串不同,t串中不能有连续相同子串

注意对边界情况的处理

code:

int n, m;
string s, t;
void solved()
{
    cin >> n >> m;
    cin >> s >> t;
    int num1 = 0, num2 = 0;
    int vis[2] = {0};
    for (int i = 0; i < s.size() - 1; ++i)
    {
        if (s[i] == s[i + 1])
        {
            num1++;
            vis[s[i] - '0'] = 1;
        }
    }
    int flag = 0;
    if (t[0] == t[t.size() - 1])
        flag = 1;
    for (int i = 0; i < t.size() - 1; ++i)
    {
        if (t[i] == t[i + 1])
            num2++;
    }
    if (num1 == 0)
    {
        cout << "YES" << endl;
        return;
    }
    if (num2 != 0 || flag == 0)
    {
        cout << "NO" << endl;
    }
    else
    {
        if ((vis[0] == 1 && vis[1] == 1))
        {
            cout << "NO" << endl;
        }
        else if ((vis[0] == 1 && t[0] == '0') || (vis[1] == 1 && t[0] == '1'))
        {
            cout << "NO" << endl;
        }
        else
        {
            cout << "YES" << endl;
        }
    }
}

C. Qingshan Loves Strings 2

思路:

首先,s串中的0和1数目相等才可以构造。

构造双指针遍历l,r,

如果s[l]==s[r],直接跳过,l++,r--,

如果s[l]!=s[r],分两种情况

  1. s[l]=“0”,则在r后面插入,r更新为r+2;
  2. s[l]=“1”,则在l前面插入,l不变,r更新为r+2

code

void solved()
{
    cin >> n;
    string s;
    cin >> s;
    vector<int> ans;
    int num0 = count(s.begin(), s.end(), '0');
    int num1 = n - num0;
    if (num1 != num0)
    {
        cout << -1 << endl;
        return;
    }
    else
    {
        int l = 0, r = n - 1;
        while (l < r)
        {
            if (s[l] != s[r])
            {
                l++;
                r--;
            }
            else
            {
                if (s[l] == '0')
                {
                    ans.push_back(r + 1);
                    s.insert(r + 1, "01");
                    r += 2;
                }
                else
                {
                    ans.push_back(l);
                    s.insert(l, "01");
                    r += 2;
                }
            }
        }
    }
    cout << ans.size() << endl;
    for (auto i : ans)
        cout << i << " ";
    cout << endl;
}

D. Doremy's Connecting Plan

思路:当所有a[i]<i**c时,那么没有节点可以合并,因为任意两个合并a[i]+a[j]<(i+j)c<ij*c

当a[i]>=i*c时,就可以和a[1]合并,故所有节点优先和1合并

计算a[i]-i*c然后按降序合并

code

void solved()
{
    cin >> n >> c;
    vector<pair<int, int>> a(n - 1);
    for (int i = 1; i <= n; ++i)
    {
        int tot;
        cin >> tot;
        if (i != 1)
            a[i - 2] = {tot - i * c, i};
        b[i] = tot;
    }
    sort(a.begin(), a.end(),greater<pair<int,int>>());
    int tot = b[1];
    for (int i = 0; i <= n - 2; ++i)
    {
        
        if (a[i].first + tot < 0)
        {
            cout << "NO" << endl;
            return;
        }
        tot += b[a[i].second];
    }
    cout << "YES" << endl;
}
posted @ 2023-10-30 12:50  bhxyry  阅读(30)  评论(0)    收藏  举报