1. 程式人生 > 實用技巧 >Codeforces Global Round 10(A->D(環問題))

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;
    }
}