首页 > 其他分享 >Codeforces Round 906 (Div. 2) A-E1

Codeforces Round 906 (Div. 2) A-E1

时间:2023-10-30 11:58:07浏览次数:33  
标签:... 906 cout int cin 字符串 Div E1 题意

比赛地址

A. Doremy's Paint 3

题意:给出一个数组\(b\),问能否通过重新排序使得数组满足\(b_1+b_2=b_2+b_3=...=b_{n-1}+b_{n}\)

Solution

首先判断元素个数

如果是1,则满足条件

如果是2,需判断不同元素个数的差是否小于等于1

其余的均不满足条件

void solve()
{
    int n;
    cin >> n;
    set<int> st;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        st.insert(a[i]);
    }
    if (st.size() == 1)
    {
        cout << "Yes\n";
    }
    else if (st.size() > 2)
    {
        cout << "No\n";
    }
    else
    {
        int cnt1 = 0, cnt2 = 0;
        for (int i = 1; i <= n; i++)
        {
            if (a[i] == a[1])
                cnt1++;
            else
                cnt2++;
        }
        if(abs(cnt1-cnt2)<=1)
        {
        	cout<<"Yes\n";
        }else
        {
        	cout<<"No\n";
        }
    }
}

B. Qingshan Loves Strings

题意:给出两个01串\(s,t\),问能否通过若干次(可以是0次)以下操作,使得\(s\)中相邻的字符都不同

操作:向\(s\)中任意一个位置插入字符串\(t\)

Solution

字符串\(t\)内的相邻元素都不同才可行,再考虑\(s\)的情况

如果\(s\)中有相邻的0,则\(t\)的最左和最右都必须是1

如果\(s\)中有相邻的1,则\(t\)的最左和最右都必须是0

如果既有相邻的0又有相邻的1,则不可行

void solve()
{
    int n, m;
    cin >> n >> m;
    string s, t;
    cin >> s >> t;
    int flag = 1;
    for (int i = 0; i < n - 1; i++)
    {
        if (s[i] == s[i + 1])
        {
            flag = 0;
            break;
        }
    }
    if (flag)
    {
        cout << "Yes\n";
        return;
    }
    flag = 1;
    for (int i = 0; i < m - 1; i++)
    {
        if (t[i] == t[i + 1])
        {
            flag = 0;
            break;
        }
    }
    if (!flag)
    {
        cout << "No\n";
        return;
    }
    int flag0 = 0, flag1 = 0;
    for (int i = 0; i < n - 1; i++)
    {
        if (s[i] == s[i + 1] && s[i] == '0')
        {
            flag0 = 1;
        }
        else if (s[i] == s[i + 1] && s[i] == '1')
        {
            flag1 = 1;
        }
    }
    if (t[0] != t[m - 1])
    {
        cout << "No\n";
        return;
    }
 
    if (flag0 && !flag1 && t[0] == '1')
    {
        cout << "Yes\n";
    }
    else if (!flag0 && flag1 && t[0] == '0')
    {
        cout << "Yes\n";
    }
    else
        cout << "No\n";
}

C. Qingshan Loves Strings 2

题意:给出一个01串\(s\),构造一个操作序列,使得最后得到的字符串满足\(s_i=S_{n-i+1}(1\le i \le n)\)

操作:向任意一个位置插入字符串\("01"\)

Solution

首先,原字符串的0和1的个数必须相同,不然无解

对于一个字符串,假设前\(x\)位和后\(x\)位已经满足条件了,那么继续考虑第\((x+1)\)位

假设它们都是1,那么向左边的1的左边进行一次操作,这样会使得字符串变为\(...011...1...\)

假设它们都是0,那么向右边的0的右边进行一次操作,这样会使得字符串变为\(...0...001...\)

如此进行模拟即可

void solve()
{
    int n;
    cin >> n;
    string s;
    cin >> s;
    if (n & 1)
    {
        cout << "-1\n";
        return;
    }
    int flag = 1;
    int cnt1 = 0, cnt0 = 0;
 
    for (int i = 0; i < n / 2; i++)
    {
        if (s[i] != s[n - i])
        {
            flag = 0;
            break;
        }
    }
    if (flag)
    {
        cout << "0\n";
        cout << "\n";
        return;
    }
    for (int i = 0; i < n; i++)
    {
        if (s[i] == '1')
        {
            cnt1++;
        }
        else
            cnt0++;
    }
    if (cnt1 != cnt0)
    {
        cout << "-1\n";
        return;
    }
    for (int i = 501; i <= 500 + n; i++)
    {
        a[i] = s[i - 501] - '0';
    }
 
    int l = 501, r = 500 + n;
    int ll = 501, rr = 500 + n;
    vector<int> ans;
 
    while (l < r)
    {
        int len = rr - ll + 1;
        if (a[l] != a[r])
        {
            l++;
            r--;
        }
        else if (a[l] == 1)
        {
            ans.push_back(l - ll);
            a[l - 1] = 1;
            ll -= 2;
            l--;
            r--;
        }
        else
        {
            ans.push_back(len - (rr - r));
            a[r + 1] = 0;
            rr += 2;
            r++;
            l++;
        }
    }
    cout << ans.size() << "\n";
    for (auto it : ans)
    {
        cout << it << " ";
    }
    cout << "\n";
}

D. Doremy's Connecting Plan

题意:给出一个\(n\)个点,初始没有边的无向图,每次可以进行以下操作:

如果\(\sum \limits_S a_k >=i \times j \times c\)(S表示点\(i,j\)各自的联通分量的并集),则在\(i,j\)连接一条无向边

问是否能够使得无向图变成连通图

Solution

贪心,考虑\(u,v\)如果可以连接的话,假设\(a_u=\frac{u\times v \times c}{2}\)

那么对于\(1,u\),因为\(v \ge 2\),所以\(a_u \ge u \times c\)

所以如果可以连边,则一定可以把点1与其相连

struct node
{
    int x, y;
    bool operator<(const node &t) const &
    {
        if (y * k - x != t.y * k - t.x)
            return y * k - x < t.y * k - t.x;
        return y < t.y;
    }
} e[N];

void solve()
{

    cin >> n >> k;
    // vector<int> a(n + 1);
    for (int i = 1; i <= n; i++)
    {
        int x;
        cin >> x;
        a[i] = x;
        e[i].x = x;
        e[i].y = i;
    }
    sort(e + 2, e + 1 + n);
    for (int i = 2; i <= n; i++)
    {
        if (a[1] + e[i].x < e[i].y * k)
        {
            cout << "No\n";
            return;
        }
        else
        {
            a[1] += e[i].x;
        }
    }
    cout << "Yes\n";
}

E1. Doremy's Drying Plan (Easy Version)

题意:初始\([1,n]\)全为0,给出\(m\)个区间,区间范围是\(1 \le l \le r \le n\),第\(i\)个区间对\([l_i,r_i]\)进行+1操作,现在最多可以删去两个区间,问删完后\([1,n]\)有多少个点是0

Solution

我们先假设不删任何区间,最后得到的\([1,n]\)的情况

对于每个区间,它们覆盖的点的大小可能是1,2,...,m

考虑两种情况:

1.删去两个覆盖点的大小为1数量最多的区间

2.枚举所有大小为2的点,我们可以处理出来哪对区间覆盖在了这个点上面,然后分别统计删去了这些区间对后的答案即可

void solve()
{
    int n, m, k;
    cin >> n >> m >> k;
    for (int i = 1; i <= n; i++)
    {
        a[i] = a0[i] = a1[i] = vis[i] = 0;
    }
    vector<node> v;
    for (int i = 1; i <= m; i++)
    {
        cin >> l[i] >> r[i];
        v.push_back({l[i], 1, i});
        v.push_back({r[i] + 1, -1, i});
    }
 
    for (int i = 1; i <= m; i++)
    {
        a[l[i]]++;
        a[r[i] + 1]--;
    }
 
    for (int i = 1; i <= n; i++)
    {
        a[i] = a[i - 1] + a[i];
    }
 
    for (int i = 1; i <= n; i++)
    {
        a0[i] = a0[i - 1] + (a[i] == 0);
        a1[i] = a1[i - 1] + (a[i] == 1);
    }
 
    int cnt0 = a0[n];
    int cnt1 = 0;
    vector<int> v1;
    for (int i = 1; i <= m; i++)
    {
        v1.push_back(a1[r[i]] - a1[l[i] - 1]);
    }
    sort(v1.begin(), v1.end());
    sort(v.begin(), v.end());
    int ans = cnt0 + v1[m - 1] + v1[m - 2];
 
    map<pii, int> mp;
    set<int> st;
    int pos = 0;
    for (int i = 1; i <= n; i++)
    {
        while (pos < (int)(v.size()) && v[pos].x == i)
        {
            if (v[pos].y == 1)
            {
                st.insert(v[pos].idx);
            }
            else
            {
                st.erase(v[pos].idx);
            }
            pos++;
        }
        if (st.size() == 2)
        {
            int x = *(st.begin()), y = *(st.rbegin());
            if (x > y)
                swap(x, y);
            mp[{x, y}]++;
            // cout<<i<<":"<<x<<" "<<y<<"\n";
        }
    }
    for (auto &it : mp)
    {
        int xx = it.first.first, yy = it.first.second;
        int res1 = a1[r[xx]] - a1[l[xx] - 1];
        int res2 = a1[r[yy]] - a1[l[yy] - 1];
        int sum = it.second + res1 + res2;
        ans = max(ans, sum + cnt0);
    }
 
    cout << ans << "\n";
}

标签:...,906,cout,int,cin,字符串,Div,E1,题意
From: https://www.cnblogs.com/HikariFears/p/17797430.html

相关文章

  • 无涯教程-Clojure - Accessing Individual Fields函数
    可以通过与结构对象一起访问键来访问结构的各个字段。AccessingIndividual-语法:keystructure-name参数   - "key"是结构中的键值,"structure-name"是作为相应关键字的结构。返回值 - 将返回与键关联的值。以下程序显示了有关如何使用它的示例。AccessingI......
  • Codeforces Round 904 (Div. 2) C. Medium Design(前缀和+差分)
    CodeforcesRound904(Div.2)C.MediumDesign思路:因为出现的线段应该为不相同的线段,所以最小值应该为\(1\)或\(m\)因此我们可以通过差分储存线段范围内的加值,再用前缀和表示这个范围内的最大加值sl为不包含\(1\)的线段的差分,sr为不包含\(m\)的线段差分记录用于差分的......
  • js聚焦并将光标定位到输入框和可编辑DIV的最后
    //聚焦并将光标定位的文本末尾---div//letdom=$('.demonstrate-li-input').eq(i).focus()//letrange=document.createRange()//创建一个新的范围对象//letsel=window.getSelection()//获取当前选区对象......
  • 卸载oracle11g
    1.卸载1.1停止使用Oracle的服务停用oracle服务,进入计算机管理,在服务中,找到oracle开头的所有服务,右击选择停止。1.2.运行卸载Oracle数据库程序在开始菜单中找到Oracle安装产品,点击运行Oracle自带的卸载程序UniversalInstaller工具卸载。1.3.删除使用Oracle的服......
  • Pinely Round 2 (Div. 1 + Div. 2) (CF1863)
    本来开了某场远古Div1,然后学了一堆前置知识至今仍然不会E。换一场写来得及吗?A.Channel模拟,略。B.SplitSortDescription给你一个长度为\(n\)的排列。每次操作你可以选择一个数\(x\),然后类似于快速排序地把小于\(x\)和大于等于\(x\)的分成两个序列,把它们拼在一起......
  • Codeforces Round 904 (Div. 2)
    A.没想到是暴力,做的很晚B.手玩一下即可C.MediumDesign给定一个长为\(n\)的数组\(a\),和若干条线段\([l_i,r_i]\),你可以选择这其中的任何若干条线段,并让\(a_l\sima_r\)均\(+1\).请你计算可以得到的\(\max(a)-\min(a)\).这题本来想的是先把所有的加进去,得到......
  • 「题解」Codeforces Round 905 (Div. 3)
    before终于有一篇题解是一次性更所有题的了。A.MorningProblemA.MorningSol&Code根据题意模拟即可。#include<bits/stdc++.h>typedeflonglongll;intmin(inta,intb){returna<b?a:b;}intmax(inta,intb){returna>b?a:b;}intT;int......
  • 【算法题】2906. 构造乘积矩阵
    题目:给你一个下标从0开始、大小为n*m的二维整数矩阵grid,定义一个下标从0开始、大小为n*m的的二维矩阵p。如果满足以下条件,则称p为grid的乘积矩阵:对于每个元素p[i][j],它的值等于除了grid[i][j]外所有元素的乘积。乘积对12345取余数。返回grid的乘积矩......
  • Codeforces 1786 / Codeforces Round #850 (Div.2)
    CodeforcesRound#850(Div.2)https://codeforces.com/contest/1786ProblemA1Non-alternatingDeck(easyversion)ProblemA2AlternatingDeck(hardversion)注意到最多进行\(O(\sqrtn)\)步,直接模拟即可。ProblemBCakeAssemblyLine题目保证了一定是\(n\)个蛋......
  • Codeforces Round 905 div2 F题
    记答案为\(ans_i\),表示从1到i次修改出现的字典序最小的数组a,\(c\)数组表示\(ans_i\)出现之后,所有修改的累加和。用一个vector存一下\(ans_i\)之后的所有修改。从1到q遍历每一次修改时,对\(c\)数组进行区间赋值操作,如果\(c\)数组中第一个不为0的数<0,那么\(ans_i\)加上\(c\)中的......