Codeforces Round #604 (Div. 2)

A. Beautiful String

$solution:$

直接暴力即可。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read(){
    int f=1,ans=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
    return ans*f;
}
const int MAXN=100001;
int N;
char str[MAXN]; 
int main(){
    int T=read();
    while(T--){
        scanf("%s",str+1);N=strlen(str+1);
        if(N==1){
            if(str[1]=='?'){
                printf("a\n");
                continue;
            }
            printf("%c",str[1]);
            continue;
        }bool ff=1;
        for(int i=1;i<=N;i++){
            if(str[i]!='?') continue;
            bool flag=0;
            for(char c='a';c<='c';c++){
                if(str[i-1]!=c&&c!=str[i+1]){
                    str[i]=c;
                    flag=1;
                    break;
                }
            }if(!flag){
                printf("-1\n");ff=0;
                break;
            }
        }
        for(int i=1;i<=N;i++) if(str[i]==str[i-1]){
            printf("-1\n");
            ff=0;
            break;
        }
        if(ff){
            for(int i=1;i<=N;i++) printf("%c",str[i]);
            printf("\n"); 
        }
    } return 0;
}
View Code

B. Beautiful Numbers

$solution:$

直接模拟即可。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<climits>
using namespace std;
inline int read(){
    int f=1,ans=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
    return ans*f;
}
const int MAXN=200001;
struct Segment{
    int Minn[MAXN<<2],Maxn[MAXN<<2];
    void clear(){memset(Minn,127/3,sizeof(Minn)),memset(Maxn,-127/3,sizeof(Maxn));return;}
    void Modify(int k,int l,int r,int ps,int w){
        if(l==r){Minn[k]=Maxn[k]=w;return;}
        int mid=l+r>>1;
        if(ps<=mid) Modify(k<<1,l,mid,ps,w);
        if(mid<ps) Modify(k<<1|1,mid+1,r,ps,w);
        Minn[k]=min(Minn[k<<1],Minn[k<<1|1]);
        Maxn[k]=max(Maxn[k<<1],Maxn[k<<1|1]);
    }
    int QMaxn(int k,int l,int r,int x,int y){
        if(x<=l&&r<=y) return Maxn[k];
        int res=0,mid=l+r>>1;
        if(x<=mid) res=max(res,QMaxn(k<<1,l,mid,x,y));
        if(mid<y) res=max(res,QMaxn(k<<1|1,mid+1,r,x,y));
        return res;
    }
    int QMinn(int k,int l,int r,int x,int y){
        if(x<=l&&r<=y) return Minn[k];
        int res=INT_MAX,mid=l+r>>1;
        if(x<=mid) res=min(res,QMinn(k<<1,l,mid,x,y));
        if(mid<y) res=min(res,QMinn(k<<1|1,mid+1,r,x,y));
        return res;
    }
}segment;
int N,A[MAXN],ps[MAXN];
int main(){
    int T=read();
    while(T--){
        segment.clear();N=read();
        for(int i=1;i<=N;i++) A[i]=read(),ps[A[i]]=i;
        for(int i=1;i<=N;i++) segment.Modify(1,1,N,i,A[i]);
        int l=INT_MAX,r=INT_MIN;
        for(int i=1;i<=N;i++){
            l=min(l,ps[i]),r=max(r,ps[i]);
            if(r-l+1==i&&segment.QMaxn(1,1,N,l,r)==i&&segment.QMinn(1,1,N,l,r)==1) printf("1");
            else printf("0");
        }printf("\n");
    }return 0;
}
View Code

C. Beautiful Regional Contest

$solution:$

考虑枚举金牌数量,发现银牌及铜牌分数线是单调增,直接维护即可。时间复杂度 $O(n)$ 。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
inline int read(){
    int f=1,ans=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
    return ans*f;
}
const int MAXN=200001;
int A,B,C,D,Ans[MAXN],Ans1[MAXN],Ans2[MAXN];
void check(){
    for(int i=1;i<A+B+C+D;i++) if(abs(Ans[i+1]-Ans[i])!=1) return;
    printf("YES\n");
    for(int i=1;i<=Ans[0];i++) printf("%d ",Ans[i]);printf("\n");exit(0);
}
int main(){
    A=read(),B=read(),C=read(),D=read();
    int res=(A+B+C+D+1)/2;
    if(A+C==res){
        Ans1[0]=0,Ans2[0]=0;
        for(int i=1;i<=A;i++) Ans1[++Ans1[0]]=0;
        for(int i=1;i<=C;i++) Ans1[++Ans1[0]]=2;
        for(int i=1;i<=B;i++) Ans2[++Ans2[0]]=1;
        for(int i=1;i<=D;i++) Ans2[++Ans2[0]]=3;
        int tot1=1,tot2=1;Ans[0]=0;
        while(tot1<=Ans1[0]&&tot2<=Ans2[0]) Ans[++Ans[0]]=Ans1[tot1],Ans[++Ans[0]]=Ans2[tot2],tot1++,tot2++;
        while(tot1<=Ans1[0]) Ans[++Ans[0]]=Ans1[tot1++];
        while(tot2<=Ans2[0]) Ans[++Ans[0]]=Ans2[tot2++];
        check();
    }
    if(B+D==res){
        Ans1[0]=0,Ans2[0]=0;
        for(int i=1;i<=B;i++) Ans1[++Ans1[0]]=1;
        for(int i=1;i<=D;i++) Ans1[++Ans1[0]]=3;
        for(int i=1;i<=A;i++) Ans2[++Ans2[0]]=0;
        for(int i=1;i<=C;i++) Ans2[++Ans2[0]]=2;
        int tot1=1,tot2=1;Ans[0]=0;
        while(tot1<=Ans1[0]&&tot2<=Ans2[0]) Ans[++Ans[0]]=Ans1[tot1],Ans[++Ans[0]]=Ans2[tot2],tot1++,tot2++;
        while(tot1<=Ans1[0]) Ans[++Ans[0]]=Ans1[tot1++];
        while(tot2<=Ans2[0]) Ans[++Ans[0]]=Ans2[tot2++];
        check();
    }
        printf("NO\n");return 0;
    return 0;
}
View Code

D. Beautiful Sequence

$solution:$

考虑奇偶位拆开考虑,因为在奇位或偶位都呈不下降,且差为 $0,2$ ,暴力维护最后 $check$ 即可,时间复杂度 $O(n)$ 。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
inline int read(){
    int f=1,ans=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
    return ans*f;
}
const int MAXN=200001;
int A,B,C,D,Ans[MAXN],Ans1[MAXN],Ans2[MAXN];
void check(){
    for(int i=1;i<A+B+C+D;i++) if(abs(Ans[i+1]-Ans[i])!=1) return;
    printf("YES\n");
    for(int i=1;i<=Ans[0];i++) printf("%d ",Ans[i]);printf("\n");exit(0);
}
int main(){
    A=read(),B=read(),C=read(),D=read();
    int res=(A+B+C+D+1)/2;
    if(A+C==res){
        Ans1[0]=0,Ans2[0]=0;
        for(int i=1;i<=A;i++) Ans1[++Ans1[0]]=0;
        for(int i=1;i<=C;i++) Ans1[++Ans1[0]]=2;
        for(int i=1;i<=B;i++) Ans2[++Ans2[0]]=1;
        for(int i=1;i<=D;i++) Ans2[++Ans2[0]]=3;
        int tot1=1,tot2=1;Ans[0]=0;
        while(tot1<=Ans1[0]&&tot2<=Ans2[0]) Ans[++Ans[0]]=Ans1[tot1],Ans[++Ans[0]]=Ans2[tot2],tot1++,tot2++;
        while(tot1<=Ans1[0]) Ans[++Ans[0]]=Ans1[tot1++];
        while(tot2<=Ans2[0]) Ans[++Ans[0]]=Ans2[tot2++];
        check();
    }
    if(B+D==res){
        Ans1[0]=0,Ans2[0]=0;
        for(int i=1;i<=B;i++) Ans1[++Ans1[0]]=1;
        for(int i=1;i<=D;i++) Ans1[++Ans1[0]]=3;
        for(int i=1;i<=A;i++) Ans2[++Ans2[0]]=0;
        for(int i=1;i<=C;i++) Ans2[++Ans2[0]]=2;
        int tot1=1,tot2=1;Ans[0]=0;
        while(tot1<=Ans1[0]&&tot2<=Ans2[0]) Ans[++Ans[0]]=Ans1[tot1],Ans[++Ans[0]]=Ans2[tot2],tot1++,tot2++;
        while(tot1<=Ans1[0]) Ans[++Ans[0]]=Ans1[tot1++];
        while(tot2<=Ans2[0]) Ans[++Ans[0]]=Ans2[tot2++];
        check();
    }
        printf("NO\n");return 0;
    return 0;
}
View Code

E. Beautiful Mirrors

$solution:$

设 $f_i$ 表示从 $i$ 到 $N$ 的期望步数,则 $f_i=p_i\cdot f_{i+1}+(1-p_i)\cdot f_1$ 。

考虑将 $f_i$ 表示成 $a_i\cdot f_1+b_i$ 的形式。推一下 $a_i,b_i$ 后 $f_1=a_1\cdot f_1+b_1$ ,所以 $f_1=\dfrac{b_1}{1-a_1}$ 。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
#define mod 998244353
using namespace std;
inline int read(){
    int f=1,ans=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
    return ans*f;
}
const int MAXN=200011;
int Mod(int x){return (((x%mod)+mod)%mod);} 
int A[MAXN],B[MAXN],P[MAXN];
int ksm(int a,int b){
    int ans=1;
    while(b){
        if(b&1) ans*=a,ans%=mod;
        a*=a,a%=mod;b>>=1;
    }return ans;
}
int N;
signed main(){
    N=read();
    for(int i=1;i<=N;i++){
        int u=read();
        P[i]=u*ksm(100,mod-2)%mod;
    }
    for(int i=N;i>=1;i--){
        A[i]=Mod((A[i+1]*P[i]%mod)+Mod(1-P[i])),B[i]=1+B[i+1]*P[i],B[i]%=mod;
    }
    int fz=B[1],fm=Mod(1-A[1]);
    printf("%lld\n",fz*ksm(fm,mod-2)%mod);return 0;
}
View Code

F. Beautiful Bracket Sequence (easy version)

$solution:$

考虑深度最大即为在字符串中为 $(((((()))))$ ,深度=左括号个数=右括号个数。

考虑在枚举,若 $[1-i]$ 中出现 $j$ 个左括号,$(i,N]$ 中出现 $j$ 个右括号,其计算个数可以通过简单的组合数得到。时间复杂度 $O(n^2)$ 。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define int long long
#define mod 998244353
using namespace std;
inline int read(){
    int f=1,ans=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
    return f*ans;
}
const int MAXN=100010;
int Ans,N,S1[MAXN],S2[MAXN],S3[MAXN],inv[MAXN],ifac[MAXN],fac[MAXN]; 
int C(int a,int b){return a<b?0:fac[a]*ifac[b]%mod*ifac[a-b]%mod;}
char str[MAXN];
signed main(){
//    freopen("2.in","r",stdin);
    fac[0]=fac[1]=ifac[0]=ifac[1]=inv[1]=1;
    for(int i=2;i<MAXN;i++) fac[i]=fac[i-1]*i%mod,inv[i]=(mod-mod/i)*inv[mod%i]%mod,ifac[i]=ifac[i-1]*inv[i]%mod;
    scanf("%s",str+1);N=strlen(str+1);
    for(int i=1;i<=N;i++){
        S1[i]=S1[i-1],S2[i]=S2[i-1],S3[i]=S3[i-1];
        if(str[i]=='(') S1[i]++;if(str[i]==')') S2[i]++;if(str[i]=='?') S3[i]++;
    }
    for(int i=1;i<=N;i++){
        for(int j=1;j<=i;j++){
            int res1=j-S1[i],res2=j-(S2[N]-S2[i]);
            int nw1=S3[i],nw2=S3[N]-S3[i];
            if(res1<0||res2<0||nw1<0||nw2<0) continue;
            if(res1>nw1||res2>nw2) continue;
            Ans+=C(nw1,res1)*C(nw2,res2)%mod*j%mod;Ans%=mod;
        }
    }printf("%lld\n",Ans);return 0;
}
View Code

 

posted @ 2019-12-06 17:32  siruiyang_sry  阅读(181)  评论(0编辑  收藏  举报