Codeforces Round #821 (Div. 2) ABCD1

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;
}
posted @ 2022-09-20 20:53  高尔赛凡尔娟  阅读(100)  评论(0编辑  收藏  举报