zoukankan      html  css  js  c++  java
  • Codeforces Round #689题解

    A题

    循环构造bac即可,因为题目是小于等于,我看成了等于所以构造的复杂了点

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    int main(){
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        while(t--){
            int n,k;
            cin>>n>>k;
            string res="";
            int i;
            for(i=0;i<k;i++){
                res+='a';
            }
            n-=k;
            int x=0;
            for(i=0;i<n;i++){
                if(x%3==0){
                    res+='b';
                }
                else if(x%3==1){
                    res+='c';
                }
                else{
                    res+='a';
                }
                x++;
            }
            cout<<res<<endl;
     
        }
    }
    View Code

    B题

    直接枚举三维加上一些剪枝,复杂度能够接受

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e5+10;
    int sum[1010][1010];
    string s[N];
    int main(){
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        while(t--){
            int n,m;
            cin>>n>>m;
            int i,j;
            memset(sum,0,sizeof sum);
            for(i=1;i<=n;i++){
                cin>>s[i];
                s[i]=" "+s[i];
            }
            for(i=1;i<=n;i++){
                for(j=1;j<=m;j++){
                    sum[i][j]=sum[i][j-1]+(s[i][j]=='*');
                }
            }
            int ans=0;
            for(i=1;i<=n;i++){
                for(j=1;j<=m;j++){
                    for(int k=i;k<=n;k++){
                        if(j+k-i>m||j-k+i<1)
                            break;
                        if(sum[k][j+k-i]-sum[k][j-k+i-1]!=2*(k-i)+1)
                            break;
                        ans++;
                    }
                }
            }
            cout<<ans<<endl;
        }
    }
    View Code

    C题

    容斥思想,找到后缀中最前面的使得后面都是按序,这样答案就是1-前面都不符合的情况

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e5+10;
    int a[N];
    int p[N];
    int main(){
        //ios::sync_with_stdio(false);
        int t;
        cin>>t;
        while(t--){
            int n,m;
            cin>>n>>m;
            int i;
            for(i=1;i<=n;i++){
                scanf("%d",&a[i]);
            }
            int last=n+1;
            for(int i=n;i>0;i--){
                if(a[i]==i){last=i;}
                else break;
            }
            double ans=1;
            for(i=1;i<=m;i++){
                int pos;
                double cnt;
                scanf("%d%lf",&pos,&cnt);
                if(pos>=last-1){
                    ans=ans*(1-cnt);
                }
            }
            int sign=0;
            for(i=2;i<=n;i++){
                if(a[i]-a[i-1]!=1){
                    sign=1;
                }
            }
            if(!sign){
                cout<<"1.000000"<<endl;
            }
            else
            printf("%.6f
    ",1-ans);
        }
    }
    View Code

    D题

    首先排序,那么之后就是一种分治的思想,根据mid不断往两边,用一个map存所有的可能性,这里需要二分一下边界,之后判断所有情况即可

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e5+10;
    int n,q;
    int a[N];
    int b[N];
    map<ll,int> m1;
    ll sum[N];
    vector<int> num;
    void solve(int l,int r){
        if(l>r)
            return ;
        if(l==r){
            m1[a[l]]=1;
            return ;
        }
        int mid=(a[l]+a[r])/2;
        int l1=l,r1=r;
        while(l1<r1){
            int tmp=l1+r1+1>>1;
            if(a[tmp]<=mid)
                l1=tmp;
            else
                r1=tmp-1;
        }
        m1[(sum[l1]-sum[l-1])]=1;
        m1[(sum[r]-sum[l1])]=1;
        if(a[l1]!=a[l]||(l1==l))
            solve(l,l1);
        if(a[l1+1]!=a[r]||(l1+1==r))
            solve(l1+1,r);
    }
    int main(){
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        while(t--){
            m1.clear();
            cin>>n>>q;
            int i;
            for(i=1;i<=n;i++){
                cin>>a[i];
                sum[i]=0;
            }
            sum[n+1]=0;
            for(i=1;i<=q;i++){
                cin>>b[i];
            }
            sort(a+1,a+1+n);
            for(i=1;i<=n;i++){
                sum[i]=a[i]+sum[i-1];
            }
            solve(1,n);
            m1[sum[n]]=1;
            for(i=1;i<=q;i++){
                if(m1[b[i]]){
                    cout<<"Yes"<<endl;
                }
                else{
                    cout<<"No"<<endl;
                }
            }
        }
    }
    View Code

    E题

    观察到数据范围这么大,一般都会有规律在里面,首先比较容易想到的是分类讨论

    分x和y的关系,x>y容易讨论,现在重点讨论x<y

    第一步的贪心比较好想,因为y>x所以我们要防止的就是不要溢出,因为所有的小于下界都可以通过先+y,再-x控制

    那么贪心的思路就是不断-x,在不能减的时候+y,这样是最不可能溢出的情况。

    但是问题是现在的数据有点大,所以肯定有突破口,观察数据范围,x只有1e6,并且我们每次都是一直-x到不行

    所以可以按x的模数分类,到达过已经判定合法的状态的情况下,那么一定是yes

    剩下就是讨论溢出的问题了

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e6+10;
    int st[N];
    int main(){
        ios::sync_with_stdio(false);
        ll k,l,r,t,x,y;
        cin>>k>>l>>r>>t>>x>>y;
        if(x>y){
            if(k+y>r){
                t--;
                k-=x;
            }
            if(k<l){
                cout<<"No"<<endl;
                return 0;
            }
            ll tmp=(k-l)/(x-y);
            if(t<=tmp){
                cout<<"Yes"<<endl;
            }
            else{
                cout<<"No"<<endl;
            }
        }
        else{
            while(1){
                if(st[k%x]){
                    cout<<"Yes"<<endl;
                    return 0;
                }
                t-=(k-l)/x;
                if(t<=0){
                    cout<<"Yes"<<endl;
                    return 0;
                }
                k=k-((k-l)/x*x);
                st[k%x]=1;
                k+=y;
                if(k>r){
                    cout<<"No"<<endl;
                    return 0;
                }
                if(k-x<l){
                    cout<<"No"<<endl;
                    return 0;
                }
            }
        }
    }
    View Code

     F题

    参考的某谷的思路,首先肯定是分类讨论,其他的讨论都比较简单,主要是+*的情况

    这种情况下,我们可以根据0划分成独立贡献

    那么再根据1讨论情况,对于这里要使用dp,但是普通dp一个是超时一个是炸ll

    因此肯定要有什么方法解决他,普通的dp思路很清晰,也很有道理,所以我们思考是否有一些约束性条件

    只要乘积和大于1e9,那么这段全部的肯定是乘法,这样就能降低复杂度了

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e6+10;
    int pre[N],pl[N],pr[N],pm[N];
    int a[N];
    map<char,int> m1;
    int ans[N];
    ll f[N];
    void solve(int l,int r){
        int lst=l-1;
        ll sign=1;
        int i;
        int idx=0;
        for(i=l;i<=r;i++){
            if(a[i]==1){
                if(lst+1<=i-1) pl[++idx]=lst+1,pr[idx]=i-1,pm[idx]=sign;
                sign=1;
                lst=i;
            }
            else{
                sign*=a[i];
                if(sign>1e9)
                    sign=1e9;
            }
        }
        if(lst!=r){
            pl[++idx]=lst+1,pr[idx]=r,pm[idx]=sign;
        }
        pr[0]=l-1;
        for(i=1;i<=idx;i++){
            f[i]=0;
        }
        sign=1;
        for(i=1;i<=idx;i++){
            sign*=pm[i];
            if(sign>1e9){
                sign=1e9;
                break;
            }
        }
        if(sign==1e9){
            pre[idx]=1;
        }
        else{
            for(int i=1;i<=idx;i++){
                ll mul=1;
                for(int j=i;j>=1;j--){
                    mul*=pm[j];
                    if(f[i]<f[j-1]+pl[j]-pr[j-1]-1+mul){
                        f[i]=f[j-1]+pl[j]-pr[j-1]-1+mul;
                        pre[i]=j;
                    }
                }
            }
        }
        for(int i=l;i<pl[1];i++) ans[i]=1;
        for(int i=pr[idx];i<r;i++) ans[i]=1;
        int cur=idx;
        while(cur){
            int t=pre[cur];
            for(int i=pr[t-1];i<pl[t];i++) ans[i]=1;cur=t-1;
        }
    
    }
    int main(){
        ios::sync_with_stdio(false);
        int n;
        cin>>n;
        int i;
        for(i=1;i<=n;i++){
            cin>>a[i];
        }
        m1['+']=0,m1['-']=1,m1['*']=2;
        string s;
        cin>>s;
        s=" "+s;
        int sign=0;
        for(i=1;i<(int)s.size();i++){
            sign|=(1<<m1[s[i]]);
        }
        if(sign==1||sign==2||sign==4){
            for(int i=1;i<=n;i++){
                cout<<a[i];if(i!=n) cout<<s[1];
            }
        }
        else if(sign==3){
            for(int i=1;i<=n;i++){
                cout<<a[i];if(i!=n) cout<<"+";
            }
        }
        else if(sign==6){
            bool hav=0;cout<<a[1];
            for(int i=2;i<=n;i++){
                if(!a[i]&&!hav) hav=1,cout<<"-";
                else cout<<"*";
                cout<<a[i];
            }
        }
        else{
            for(i=1;i<=n;i++){
                if(!a[i]){
                    if(i!=1) ans[i-1]=1;
                    if(i!=n) ans[i]=1;
                }
            }
            int lst=0;
            for(i=1;i<=n;i++){
                if(!a[i]){
                    solve(lst+1,i-1),lst=i;
                }
            }
            solve(lst+1,n);
            for(i=1;i<n;i++){
                cout<<a[i];
                if(ans[i]){
                    cout<<"+";
                }
                else{
                    cout<<"*";
                }
            }
            cout<<a[n]<<endl;
        }
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    Python 集合
    Python sorted()
    CodeForces 508C Anya and Ghosts
    CodeForces 496B Secret Combination
    CodeForces 483B Friends and Presents
    CodeForces 490C Hacking Cypher
    CodeForces 483C Diverse Permutation
    CodeForces 478C Table Decorations
    CodeForces 454C Little Pony and Expected Maximum
    CodeForces 313C Ilya and Matrix
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14296726.html
Copyright © 2011-2022 走看看