首页 > 其他分享 >Codeforces Round #821 (Div. 2) ABCD1

Codeforces Round #821 (Div. 2) ABCD1

时间:2022-09-20 21:00:39浏览次数:114  
标签:typedef int LL cin long ABCD1 tie Div 821

A.Consecutive Sum
https://codeforces.com/contest/1733/problem/A

题目大意:
给定一个长度为n的数组a。最多可以执行k次以下操作:

选择两个指数i和j,其中i mod k=j mod k (1≤i<j≤n)。
互换ai和aj。
完成所有操作后,你必须选择k个连续的元素,这k个元素的总和就是你的分数。找到你能得到的最高分。
input 
5
3 2
5 6 0
1 1
7
5 3
7 0 4 0 4
4 2
2 7 3 4
3 3
1000000000 1000000000 999999997
output 
11
7
15
10
2999999997

数据范围小,直接双重循环暴力跑即可

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long LL;
const int N=2002000,M=2002;
LL a[N];
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    LL T=1;
    cin>>T;
    while(T--)
    {
        LL n,k;
        cin>>n>>k;
        for(LL i=1;i<=n;i++)
        {
            cin>>a[i];
        }
        LL sum=0;
        for(LL i=1;i<=k;i++)
        {
            LL maxn=a[i];
            for(LL j=i;j<=n;j+=k)
            {
                maxn=max(maxn,a[j]);
            }
            sum+=maxn;
        }
        cout<<sum<<endl;
    }
    return 0;
}

B. Rule of League
https://codeforces.com/contest/1733/problem/B

题目大意:
n个人编号1-n在一起打羽毛球,从1和2开始两两打(1和2打一局,赢了的和3打,赢了的和4打...)

总共会打n-1局,给定一个x,y,分别表示每个人可能赢的次数和输的次数

问合理嘛?合理给出每一局可能赢的人数,不合理输出-1。
input 
5
5 2 0
8 1 2
3 0 0
2 0 1
6 3 0
output 
1 1 4 4
-1
-1
2 
-1

根据题目意思,每x或者y盘安排一个人赢即可

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long LL;
const int N=2002000,M=2002;
LL a[N];
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    LL T=1;
    cin>>T;
    while(T--)
    {
        LL n,x,y;
        cin>>n>>x>>y;
        if(x!=0&&y!=0) cout<<"-1"<<endl;
        else if(x==0&&y==0) cout<<"-1"<<endl;
        else
        {
            if(x!=0)
            {
                if((n-1)%x!=0) cout<<"-1"<<endl;
                else
                {
                    for(LL i=2;i<=n;i+=x)
                        for(LL j=1;j<=x;j++)
                            cout<<i<<" ";
                    cout<<endl;
                }
            }
            else if(y!=0)
            {
                if((n-1)%y!=0) cout<<"-1"<<endl;
                else
                {
                    for(LL i=2;i<=n;i+=y)
                        for(LL j=1;j<=y;j++)
                            cout<<i<<" ";
                    cout<<endl;
                }
            }
        }
    }
    return 0;
}

C. Parity Shuffle Sorting
https://codeforces.com/contest/1733/problem/C

题目大意:
给定一个长度为n的非负整数的数组a。

可以对其应用以下操作(至多n次):

选择两个指数l和r (1≤l<r≤n),如果al+ar是奇数,则做ar:=al。如果al+ar是偶数,则做al:=ar。
(如果ai+aj是奇数,那么右边的数字变成和左边的一样;如果ai+aj是偶数,那么左边的数字变成和右边的一样)。

找出最多n个运算的任意序列,使数组a变成非递减的顺序。可以证明,总是有可能的。请注意,您不必最小化操作的数量。

输出任意一种操作方案。
input 
3
2
7 8
5
1 1000000000 3 0 5
1
0
output 
0
2
3 4
1 2
0

年度最离谱,写了个假的智慧数据hack了自己的想法,本来半个小时就可以写完的,直接花了一个小时哈哈哈(还是之前的思路),我真是傻了

  • 分奇偶,偶奇,偶偶,奇奇四种即可
  • 其实合并起来也行,我写的繁琐了些
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long LL;
const int N=2002000,M=2002;
LL a[N];
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    LL T=1;
    cin>>T;
    while(T--)
    {
        LL n;
        cin>>n;
        for(LL i=1;i<=n;i++)
            cin>>a[i];
        if(n==1) cout<<"0"<<endl;
        else{

        if(a[1]%2==1&&a[n]%2==0)//ji ou
        {
            cout<<n-1<<endl;
            cout<<"1 "<<n<<endl;
            for(LL i=2;i<=n-1;i++)
            {
                if(a[i]%2==0) cout<<"1 "<<i<<endl;
                else cout<<i<<" "<<n<<endl;
            }
        }
        else if(a[1]%2==0&&a[n]%2==0)//ou ou
        {
            cout<<n-1<<endl;
            cout<<"1 "<<n<<endl;
            for(LL i=2;i<=n-1;i++)
            {
                if(a[i]%2==1) cout<<"1 "<<i<<endl;
                else cout<<i<<" "<<n<<endl;
            }
        }
        else if(a[1]%2==0&&a[n]%2==1)//ou ji
        {
            cout<<n-1<<endl;
            cout<<"1 "<<n<<endl;
            for(LL i=2;i<=n-1;i++)
            {
                if(a[i]%2==1) cout<<"1 "<<i<<endl;
                else cout<<i<<" "<<n<<endl;
            }
        }
        else if(a[1]%2==1&&a[n]%2==1)//ji ji
        {
            cout<<n-1<<endl;
            cout<<"1 "<<n<<endl;
            for(LL i=2;i<=n-1;i++)
            {
                if(a[i]%2==1) cout<<i<<" "<<n<<endl;
                else cout<<"1 "<<i<<endl;
            }
        }
        }
    }
    return 0;
}

D1. Zero-One (Easy Version)
https://codeforces.com/contest/1733/problem/D1

题目大意:
给你两个二进制字符串a和b,长度都是n。

选择两个索引l和r(l<r):0 变 1,1 变 0。可以操作任意次。

如果l+1=r,则操作的成本为x,否则,成本为y。
你必须找到使a等于b所需的最小成本,或者说没有办法这样做(则输出-1)。
input
4
5 8 7
01001
00101
5 7 2
01000
11011
7 8 3
0111001
0100001
5 10 1
01100
01100
output 
8
-1
6
0

贪心:
分三种情况讨论

  • 首先是考虑一下什么时候为-1呢?两个两个一组进行交换,那必然是落单了的时候,即为-1;

  • 那么如果不存在连续的情况的时候,那我们就只能老老实实的用y来进行计算,可以知道的是我们让其中的两两一组,就可以简化为sum/2*y的总数了

  • 那么如果存在连续的情况下呢?

第一种就是有连续的,但是也有非连续的,也有好多对连续的,这种我们可以把它归为一类,因为只要交错进行计算,就可以回到上面那种不连续的情况下
所以比较的种类就可以有这两种:min(sum/2y,ansx+(sum-ans2)/2y)

第二种是的确有连续的,但是没有别的数据作为交叉环节,所以就是只有唯一的这一对相邻的数据,总数也就是只有两个,那这个就必须用相邻的来跟拆分的对比了
也就是min(ansx,ans2*y)

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
typedef long long LL;
const int N=2002000,M=2002;
LL a[N];
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    LL T=1;
    cin>>T;
    while(T--)
    {
        LL n,x,y;
        cin>>n>>x>>y;
        string s;
        cin>>s;
        string c;
        cin>>c;
        LL sum=0;
        for(LL i=0;i<s.size();i++)
            if(s[i]!=c[i]) sum++;
        //cout<<sum<<endl;
        LL ans=0;
        for(LL i=0;i<s.size();i++)
        {
            if(i-1>=0&&s[i]!=c[i]&&s[i-1]!=c[i-1])
            {
                ans++;
                i++;
            }
        }
        //cout<<ans<<endl;
        if(sum%2==1) cout<<"-1"<<endl;
        else
        {
            //不存在相邻的,直接抵消
            if(ans==0) cout<<sum/2*y<<endl;
            else
            {
                //存在相邻的,要么两两互消,要么再拉一个数据
                if(sum==2&&ans==1) cout<<min(ans*x,ans*2*y)<<endl;
                else cout<<min(sum/2*y,ans*x+(sum-ans*2)/2*y)<<endl;
            }
        }
        s.clear();
        c.clear();
    }
    return 0;
}

标签:typedef,int,LL,cin,long,ABCD1,tie,Div,821
From: https://www.cnblogs.com/Vivian-0918/p/16712520.html

相关文章

  • Codeforces Round #821(Div.2) (A-C) 题解
    CodeforcesRound#821(Div.2)(A-C)  A.ConsecutiveSum大致题意给定一组共n个数据,如果俩个数的下标在modk意义下同余,则可以交换a[I]和a[j] ,求操作后一段......
  • Codeforces Round #821 (Div. 2)(持续更新)
    Preface唉LOL打到一半被迫营业开打,感觉这算是第一次自己认真的在线打CF,以我的老年人手速感觉要罚时飞起了10:35开始打到12:10顶不住了睡觉去了,E大概看了个题感觉挺有意思的......
  • Codeforces Round #819 (Div. 1 + Div. 2) and Grimoire of Code Annual Contest 2022
    Preface明天的CF一定打啊(绝对不咕),今天白天补现代作业,英语作业到哭,而且还要准备四六级,每天逼着自己背单词A.MainakandArray不难发现换中间的数不会影响答案,因此操作......
  • Codeforces Round #821 D2
    D2.Zero-One(HardVersion)我们由D1可知当我们的y小于x/2时我们可以用2y来减小相邻的cost那我们考虑要是y比较大的时候我们也可以用多个x来减小cost我们可以轻松的......
  • Codeforces Round #821 (Div. 2)
    CodeforcesRound#821(Div.2)C.ParityShuffleSorting题目大意每次操作可以选择l,r,如果\(a_l+a_r\)是奇数可以让\(a_l=a_r\),否则可以让\(a_l=a_r\),要求使用不超过n......
  • Codeforces #821 Div2(A~D2)题解
    CF#821Div2AConsecutiveSum题目:​ 选择\(i\)和\(j\),如果\(j=i+xk(x=R)\),可以交换\(i,j\)。任意选择一段长度为k的相加。思路:​ 题目等价于在下标\(mod\)k相同......
  • Workshop: Definition, Benefits, and Its Purpose for Individuals
    Workshop:Definition,Benefits,andItsPurposeforIndividualsHoldingaworkshopisoneofthecompany’seffortsinimprovingtheskillsandabilitiesofth......
  • Codeforces Round #813 (Div. 2)
    CodeforcesRound#813(Div.2)D.EmptyGraph分析我们通过简单的分析,可以得出一个结论,我们的答案一定来自于相邻两个点的位置或是最小值的两倍。我们考虑如何给构造......
  • CF round 812 div2 A-D 题解
    首先第一题TravelingSalesManProblem,给出一些坐标,就是问从原点出发,然后收集所有的点,问最少需要多少次移动这个就是求收集完那曼哈顿距离,这个距离稍加观察可以发现,就是......
  • Codeforces Round #640 (Div. 4) C. K-th Not Divisible by n
    CodeforcesRound#640(Div.4)翻译岛田小雅C.K-thNotDivisiblebyn出题人MikeMirzayanov有两个正整数\(n\)和\(k\),输出第\(k\)个不能被\(n\)整除的正整......