Codeforces Round #825 (Div. 2)(补题中)

战绩:

A. Make A Equal to B

 

实际上就只有两种操作可能,一种是遇到了不同的位置直接换,一种是换出0和1一样的个数后重新排列顺序,两种操作比较最小值输出。

复制代码
int main()
{
    cin>>T;
    while(T--)
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            ll lim;
            cin>>a[i];
            buca[a[i]]++;
        }
        for(int i=1;i<=n;i++)
        {
            ll lim;
            cin>>b[i];
            bucb[b[i]]++;
        }
        ll change=abs(bucb[0]-buca[0]);
        ll c2=0;
        for(int i=1;i<=n;i++)
        {
            if(a[i]!=b[i]) c2++;
        }
        ll ans=min(c2,change+1);
        cout<<ans<<endl;
        memset(buca,0,sizeof(buca));
        memset(bucb,0,sizeof(bucb));
    }
    return 0;
}
View Code
复制代码

B. Playing with GCD

对于每一个bi,我们可以知道它左右两个ai都必定是它的因子,相邻的两个bi要求最大公因数,那么我们构造的b数组一定要符合每个bi都是左右两个a的最小公倍数,构造出数组后再比较一遍即可。

复制代码
int main()
{
    cin>>T;
    while(T--)
    {
        cin>>n;
        a[0]=1;
        a[n+1]=1;
        for(int i=1;i<=n;i++) cin>>a[i];
        bool flag=0;
        for(int i=1;i<=n+1;i++)
        {
            b[i]=(a[i-1]*a[i])/__gcd(a[i-1],a[i]);
        }
        for(int i=2;i<=n+1;i++)
        {
            if(__gcd(b[i],b[i-1])!=a[i-1]) flag=1;
        }
        if(!flag) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}
View Code
复制代码

C1. Good Subarrays (Easy Version)

我看到的题解大多数使用的是双指针,我用的是dp的思想,但实际上大同小异。

设dp[i]代表以i为结尾的符合题意的子串数目。

那么首先,每个a[i]揭示了当前这一位的最右边的起点的最近位置,也是这一位为结尾的最大可能区间数目。

其次我们一定要保证一个区间内每一个数字都符合题意,因此dp转移方程为dp[i]=min(a[i],dp[i-1]+1),累加即可。

复制代码
int main()
{
    cin>>T;
    while(T--)
    {
        cin>>n;
        ll ans=0;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            if(i==1||a[i]==1)dp[i]=1;
            else dp[i]=min(a[i],dp[i-1]+1);
            ans+=dp[i];
        }
        cout<<ans<<endl;
    }
    return 0;
}
View Code
复制代码

D. Equal Binary Subsequences

首先,如果出现某个数字个数是奇数,那么输出-1。

假如我们的串是00001111这样子一对一对都是相同的数字,那么我们很明显一左一右一左一右的分配即可。

那么我们就每两个两个来看,如果是01或者10这样的我们就抽出一个数字。

符合条件的情况下,如果01/10出现那么后面一定还有一组01/10,那么我们两组就抽出两个不同的数字,然后我们全部循环左移或者右移,就变成了我们想要的成对子的串。

复制代码
int main()
{
    cin>>T;
    while(T--)
    {
        cin>>n;
        cin>>s;
        ll num0=0,num1=0;
        for(int i=0;i<2*n;i++) {if(s[i]=='0') num0++;else num1++;}
        if((num0&1)||(num1&1)) {cout<<"-1"<<"\n";continue;}
        ll las=0;
        cg.clear();
        for(int i=0;i<2*n;i+=2)
        {
            if(s[i]==s[i+1]) continue;
            else
            {
                if((s[i]-'0')!=las) cg.push_back(i);
                else cg.push_back(i+1);
                las=1-las;
            }
        }
        cout<<cg.size();
        for(int i=0;i<cg.size();i++) cout<<" "<<cg[i]+1;
        cout<<endl;
        for(int i=0;i<2*n;i+=2) cout<<i+1<<" ";
        cout<<endl;
    }
    return 0;
}
View Code
复制代码

 

posted @   ztlsw  阅读(41)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示