AtCoder Grand Contest 037

链接

A.Dividing a String

可以发现分成的段要么为 \(1\) 要么为 \(2\),而且能为 \(1\) 一定为 \(1\)

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 200010
using namespace std;
char s[N];
int main()
{
    scanf("%s",s+1);
    int n=strlen(s+1);
    int c=0;bool d=0;
    for(int i=1;i<=n;i++)
    {
        ++c;
        if(d || s[i]!=s[i-1]) d=false;
        else if(i==n) c--;
        else i++,d=true;
    }
    printf("%d\n",c);
    return 0;
}

B. RGB Balls

可以发现贪心匹配一定是最优的,而且只有优先匹配才能成为答案。

所以对于每种颜色的球从前往后进行匹配。

考虑这样只需要每次乘上匹配的可选方案即可。复杂度 \(O(n)\)

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 100050
#define ll long long
using namespace std;
int c[N],n;
bool work(int x)
{
    ll c0=0;
    for(int i=x;i<n;i++) c0+=c[i];
    ll p=1;
    for(int i=x-1;i>0;i--)
    {
        if(c[i]<p) p=1ll*(p*2-c[i]);
        else if(c[i]>p) c0+=c[i]-p;
        if(p>=1e16) return false;
    }
    return p<=c0+c[0];
}
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%d",&c[i]);
    int p=-1;
    for(int i=0;i<n;i++)
    if(c[i]==1){if(p==-1) p=i;else p=-2;}
    else if(c[i]) p=-2;
    if(p>=0){printf("%d\n",p==0?1:p);return 0;}
    int l=1,r=n+30,res=0;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(work(mid)) l=mid+1,res=mid;
        else r=mid-1;
    }
    printf("%d\n",res);
    return 0;
}

C.Numbers on a Circle

考虑从后往前,显然一个数字如果

posted @ 2023-09-20 18:54  Flying2018  阅读(16)  评论(0)    收藏  举报