Codeforces Global Round 10(A->D(环问题))

A:http://codeforces.com/contest/1392/problem/A

题意:

相邻的不同数可以相加合成一个数,问最后最少会剩下几个数

解析:

随便写一下,就会发现,只要数组中只要存在不同数,最后就一定能合成一个数。

所以,全相等,输出n,否则1

#include<bits/stdc++.h>
#include<map>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=2e5+20;
//const ll inf=0x3f3f3f3f3f3f3f3f;
ll a[maxn];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        int ok=0;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        if(n==1)
        {
            cout<<"1"<<endl;continue;
        }
        for(int i=2;i<=n;i++)
        {
            if(a[i]!=a[i-1])
            {
                ok=1;break;
            }
        }
        if(ok)
            cout<<"1"<<endl;
        else
            cout<<n<<endl;

    }
}

B:http://codeforces.com/contest/1392/problem/B

题意:

每次操作让当前数组的最大值去减数组的每一个数,求第k次操作的数组

解析:

列了一下,发现,k=1,变一次,k=2,变两次,k=3,变三次

对于k>1,奇数变三次,偶数变两次

模拟一下即可。

关于最大值的选择,不少人赛后被hack掉,所以建议最大值直接设为a[1]妥当。

#include<bits/stdc++.h>
#include<map>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=2e5+20;
//const ll inf=0x3f3f3f3f3f3f3f3f;
ll a[maxn];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        ll k;
        cin>>n>>k;
        ll maxx;
        cin>>a[1];
        maxx=a[1];
        for(int i=2;i<=n;i++)
            cin>>a[i],maxx=max(a[i],maxx);
        if(k==1)
        {
            for(int i=1;i<=n;i++)
            {
                cout<<maxx-a[i]<<' ';
            }
            cout<<endl;continue;
        }
            ll maxx2=maxx-a[1];
            a[1]=maxx-a[1];
            for(int i=2;i<=n;i++)
            {
                a[i]=maxx-a[i];
                maxx2=max(maxx2,a[i]);
            }
            ll maxx3=maxx2-a[1];
            a[1]=maxx2-a[1];
            for(int i=2;i<=n;i++)
            {
                a[i]=maxx2-a[i];
                maxx3=max(maxx3,a[i]);                
            }
            if(k%2==0)
            {
                for(int i=1;i<=n;i++)
                    cout<<a[i]<<" ";
                    cout<<endl;continue;
            }
            ll maxx4=maxx3-a[1];
            a[1]=maxx3-a[1];
            for(int i=2;i<=n;i++)
            {
                a[i]=maxx3-a[i];
                maxx3=max(maxx3,a[i]);                
            }            
                for(int i=1;i<=n;i++)
                    cout<<a[i]<<" ";
                    cout<<endl;            
    }
}

C:http://codeforces.com/contest/1392/problem/C

题意:

给出序列,操作:对不递减的区间里的每一个数都加1,将整个序列变成非递减序列所需要的最少操作数。

解析:

本来分析复杂了,涉及到区间问题。但是把序列倒着遍历,思路就很清晰了。

ai<ai-1,把ai增加到和ai-1相同。

以后再遇到这种情况,ai后集体跟着加1即可。

#include<bits/stdc++.h>
#include<map>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=2e5+20;
//const ll inf=0x3f3f3f3f3f3f3f3f;
ll a[maxn];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        ll ans=0;
        for(int i=n;i>1;i--)
        {
            if(a[i]<a[i-1])
                ans+=(a[i-1]-a[i]);
        }
        cout<<ans<<endl;
    }
}

D:http://codeforces.com/contest/1392/problem/D

题意:

n个人围成一圈。字符串表示每个人攻击的是左边的人还是右边的人。

合法情况:

如果一个人被攻击一次,那么他要反击那个人

如果一个人被攻击0或两次,他可以对左右任选一个攻击。

将游戏变成合法,最少需要纠正几个人?

解析:

先把环变成链

1:全L或全R的情况,

RRR->RRL,RRRR->RRLL,RRRRR->RRLRL , RRRRRR->RRLRRL

有结论,此时结果为:n/3+(n%3>0)

2:L和R均有

借助1的结论,固定到第一个a[k]!=a[0],往后记录连续和a[k]相等的,cnt++

a[i]!=a[k],记录总数sum+=cnt/3,cnt重置,k改变

注意对于cnt<3,是不需要改的,这部分肯定是符合条件的。

#include<bits/stdc++.h>
#include<map>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=2e5+20;
char s[3*maxn];
//const ll inf=0x3f3f3f3f3f3f3f3f;
ll a[maxn];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
    //    string s;
        int n;
        cin>>n;
        scanf("%s",s);
        for(int i=0;i<n;i++)
            s[i+n]=s[i];
        int k=-1;
        for(int i=1;i<n;i++)
        {
            if(s[i]!=s[0])
            {
                k=i;
                break;
            }
        }
        if(k==-1)
        {
            cout<<n/3+(n%3>0)<<endl;
            continue;
        }
        int id=k;
        ll sum=0;
        int cnt=0;
        for(int i=k;i<n+k;i++)
        {
            if(s[i]==s[id])
                cnt++;
            else
            {
                sum+=cnt/3;
                cnt=1;
                id=i;
            }
        }
        sum+=cnt/3;
        cout<<sum<<endl;
    }
}

 

posted @ 2020-08-18 17:14  liyexin  阅读(193)  评论(0编辑  收藏  举报