zoukankan      html  css  js  c++  java
  • Codeforces Round 604 Div2

    A

    题意

    给一个字符串,由a,b,c字母和?组成。 ?可以填成a,b,c中的一个。求是否存在一种填法使得:字符串不存在任何相邻位置的字母相同。存在则输出填充后的字符串,不存在输出-1

    思路

    对于任何一个位置,只有两个邻居,但是有三种填法,所以说每个问号必定可以合法填充。按规则填完后检测一下就好了。

    代码

    #include<bits/stdc++.h>
    
    using namespace std;
    const int MAX=1e5+5;
    
    char s[MAX];
    bool vis[3];
    int main()
    {
        int T;
        cin>>T;
        while(T--)
        {
            scanf("%s",s);
            int len=strlen(s);
            for(int i=1; i<len-1; i++)
            {
                if(s[i]=='?')
                {
                    if(s[i-1]!='?')
                        vis[s[i-1]-'a']=1;
                    if(s[i+1]!='?')
                        vis[s[i+1]-'a']=1;
                    for(int j=0; j<3; j++)
                        if(!vis[j])
                        {
                            s[i]=j+'a';
                            break;
                        }
                    memset(vis,0,sizeof vis);
                }
            }
            if(s[0]=='?')
                s[0]=((len>1?s[1]:'a')-'a'+1)%3+'a';
            if(s[len-1]=='?')
                s[len-1]=((len>1?s[len-2]:'a')-'a'+1)%3+'a';
            bool flag=1;
            for(int i=1;i<len;i++)
                if(s[i]==s[i-1])
                {
                    flag=0;
                    break;
                }
            if(flag)
                printf("%s
    ",s);
            else
                printf("-1
    ");
        }
    }
    
    

    B

    题意

    给定1-n的一个排列,求对于1-n的每个m,是否存在一个区间使得1-m所有数均在这个区间中。

    思路

    记录一下数i的位置,记为pos[i]。然后递推处理,记max1-i中出现的最大位置,min为最小位置。则可以保证前i个数一定出现在[min,max]之间。若此时max-min+1==i即区间长度为i则说明前i个数均在此区间内,即长为i的区间存在。

    代码

    #include<bits/stdc++.h>
    
    using namespace std;
    const int MAX=2e5+5;
    
    int pos[MAX];
    
    int main()
    {
        int T;
        cin>>T;
        while(T--)
        {
            int n,x;
            scanf("%d",&n);
            for(int i=1; i<=n; i++)
                scanf("%d",&x),pos[x]=i;
            printf("1");
            int minn=pos[1],maxx=pos[1];
            for(int i=2; i<=n; i++)
            {
                minn=min(minn,pos[i]);
                maxx=max(maxx,pos[i]);
                if(maxx-minn+1==i)
                    printf("1");
                else
                    printf("0");
            }
            printf("
    ");
        }
    }
    

    C

    题意

    比赛发牌子,给出n个队伍的过题数,发g个金牌,s个银牌,b个铜牌,使得g,s,b满足以下要求:

    • g,s,b > 0
    • g < sg < b
    • 金牌队伍过题数必须严格大于银牌队伍
    • 银牌队伍过题数必须严格大于铜牌队伍
    • 铜牌队伍过题数必须严格大于无牌队伍
    • 总奖牌数小于队伍数量一般(向下取整),即g+s+b < n/2

    思路

    贪心依次推,在满足1,3条件的前提下g尽可能少,在满足1,2,4条件的前提下s尽可能少,b取满足1,5条件的剩余结果,若都能满足则有解,否则无解。

    代码

    #include<bits/stdc++.h>
    
    using namespace std;
    const int MAX=4e5+5;
    
    int a[MAX];
    
    int main()
    {
        int T;
        cin>>T;
        while(T--)
        {
            int n;
            scanf("%d",&n);
            for(int i=0;i<n;i++)
                scanf("%d",&a[i]);
            int g=0,s=0,b=0,p=0;
            int ed=n/2;
            while(a[ed]==a[ed-1]&&ed>0)ed--;
            while(p<ed&&a[p]==a[p+1])p++;
            g=p=p+1;
            while(p<ed&&(a[p]==a[p+1]||p+1<=g*2))p++;
            s=p-g+1;
            b=ed-p-1;
            if(g==0||s==0||b==0||g>=s||g>=b)
                g=s=b=0;
            printf("%d %d %d
    ",g,s,b);
        }
    }
    

    D

    题意

    0,1,2,3这四种数,分别有a,b,c,d个,求如何排列使得序列任意相邻的两个数差距,即abs(a[i]-a[i+1]),不超过1

    思路

    很显然0必须和1相邻,3必须和2相邻,所以至少需要a1d2,所以b-=a,c-=d,然后看此时的c,d之差距是否不超过1,若是则有解,输出,否则无解。 再特判一下0,1数量全为0或者2,3数量全为0的情况即可。

    代码

    #include<bits/stdc++.h>
    
    using namespace std;
    
    int main()
    {
        int a,b,c,d;
        scanf("%d%d%d%d",&a,&b,&c,&d);
        int bb=b-a;
        int cc=c-d;
        if(a==b&&a==0&&d-c==1)
        {
            printf("YES
    3 ");
            for(int i=0;i<c;i++)
                printf("2 3 ");
            printf("
    ");
            return 0;
        }
        if(a-b==1&&c==d&&d==0)
        {
            printf("YES
    ");
            for(int i=0;i<b;i++)
                printf("0 1 ");
            printf("0
    ");
            return 0;
        }
        if(bb<0||cc<0||abs(bb-cc)>1)
        {
            printf("NO
    ");
            return 0;
        }
        printf("YES
    ");
        if(bb==cc)
        {
            for(int i=0;i<a;i++)
                printf("0 1 ");
            for(int i=0;i<bb;i++)
                printf("2 1 ");
            for(int i=0;i<d;i++)
                printf("2 3 ");
        }
        if(bb-cc==1)
        {
            printf("1 ");
            for(int i=0;i<a;i++)
                printf("0 1 ");
            for(int i=0;i<bb-1;i++)
                printf("2 1 ");
            for(int i=0;i<d;i++)
                printf("2 3 ");
        }
        if(cc-bb==1)
        {
            for(int i=0;i<a;i++)
                printf("0 1 ");
            for(int i=0;i<bb;i++)
                printf("2 1 ");
            for(int i=0;i<d;i++)
                printf("2 3 ");
            printf("2 ");
        }
        printf("
    ");
        return 0;
    }
    

    E

    题意

    一个人有n个魔镜,第i个魔镜有pi的概率说这个人好看。现在从第一个魔镜开始问起,每天问一个,若魔镜说好看则第二天继续问下一个,若说不好看则第二天从第一个魔镜重新开始问起。若第n个魔镜说好看则这个人会变开心。求让他变开心所需要的天数的期望,输出对998244353取模。

    思路

    求期望,马尔可夫链,由出边连接节点向本节点转移。可得如下模型。

    dp[i]表示由第i个魔镜开始询问到达最终状态的期望天数。
    最后一个魔镜也需要询问,所以设最终状态为dp[n+1]=0。即由最终状态转移到最终状态期望天数为0
    最终答案即为dp[1]由此模型推导得出

    [dp[1]=dp[2]*p+dp[1]*(1-p_1)+1\ Rightarrow dp[1]=dp[2]+frac 1p_1 qquad(1)\ dp[2]=dp[3]*p_2+dp[1]*(1-p_2)+1\ 代入(1)Rightarrow dp[1]=dp[3]+frac 1p_2+frac 1{p_1p_2} ]

    可得规律

    [dp[1]=dp[n+1]+frac 1p_n+frac1{p_np_{n-1}}+cdots+frac 1{p_n cdots p_1}\ Downarrow\ dp[1]=frac {p_{n-1}cdots p_1+p_{n-2}cdots p_1+cdots+p_1+1}{p_1cdots p_n} ]

    计算出此式即可。有除法取模,所以要求逆元。模数为质数,用费马小定理。乘一个1ll提升字节数防止溢出。

    代码

    #include<bits/stdc++.h>
    
    using namespace std;
    const int mod=998244353;
    
    int qpow(int a,int k)
    {
        int res=1;
        for(;k;k>>=1)
        {
            if(k&1)
                res=1ll*res*a%mod;
            a=1ll*a*a%mod;
        }
        return res%mod;
    }
    
    int inv(int x){return qpow(x,mod-2);}
    
    int main()
    {
        int a=0,b=1,n,inv100=inv(100);
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            int x;
            scanf("%d",&x);
            x=1ll*x*inv100%mod;
            a=(a+b)%mod;
            b=1ll*b*x%mod;
        }
        printf("%d
    ",(1ll*a*inv(b)%mod+mod)%mod);
    }
    
  • 相关阅读:
    最新免费网络加速器,游戏加速器下载_网络加速器永久免费版哪个好?
    HTML中特殊符号编码对照表,html特殊符号编码都有哪些?
    超融合架构在汽车行业前景及未来发展
    好用的前端开发小工具
    layui省市区三级联动城市选择
    企业超融合解决方案怎么做?超融合基础架构 超融合优势是什么?
    最新免费网络加速器
    什么是超融合?
    面临网络安全危机时需要思考的20个问题
    2019年超融合将飞速发展 三大趋势不容错过
  • 原文地址:https://www.cnblogs.com/cryingrain/p/12328086.html
Copyright © 2011-2022 走看看