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

    A题

    贪心从10开始

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=1e6+10;
    const int mod=1e9+7;
    int main(){
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        while(t--){
            ll a,b;
            cin>>a>>b;
            if(a>b){
                swap(a,b);
            }
            int cnt=0;
            b-=a;
            for(int i=10;i>=1;i--){
                if(b==0)
                    break;
                cnt+=b/i;
                b%=i;
            }
            cout<<cnt<<endl;
        }
        return 0;
    }
    View Code

    B题

    贪心

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<ll,ll> pll;
    const int N=2e5+10;
    const int M=2e6+10;
    const int inf=0x3f3f3f3f;
    const ll mod=998244353;
    int main(){
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        while(t--){
            ll a,b,c,d,n,x,y;
            cin>>a>>b>>c>>d>>n;
            ll ans=1e18;
            x=a-c,y=b-d;
            ll dd=n;
            ll tmp1=a-min(n,x);
            dd-=min(n,x);
            ll tmp2=b-min(dd,y);
            ans=min(ans,tmp1*tmp2);
            dd=n;
            tmp1=b-min(n,y);
            dd-=min(n,y);
            tmp2=a-min(dd,x);
            ans=min(ans,tmp1*tmp2);
            cout<<ans<<endl;
        }
        return 0;
    }
    View Code

    C题

    我采用的方法是找到差值的因数,从小到大枚举,看看能否达到50个

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=1e6+10;
    const int mod=1e9+7;
    vector<int> num;
    int main(){
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        while(t--){
            int n,x,y;
            cin>>n>>x>>y;
            if(x==y){
                int i;
                for(i=1;i<=n;i++)
                    cout<<x<<" ";
                cout<<endl;
                continue;
            }
            int tmp=y-x;
            int flag=0;
            for(int i=1;i<=tmp;i++){
                if(tmp%i==0){
                    num.clear();
                    int cnt=x;
                    num.push_back(x);
                    num.push_back(y);
                    if((n-1)*i<tmp)
                        continue;
                    if(num.size()==n){
                        flag=1;
                        break;
                    }
                    while(cnt+i<y&&num.size()<n){
                        num.push_back(cnt+i);
                        cnt+=i;
                    }
                    if(num.size()==n){
                        flag=1;
                        break;
                    }
                    if(num.size()>n){
                        break;
                    }
                    cnt=x;
                    while(cnt-i>=1&&num.size()<n){
                        num.push_back(cnt-i);
                        cnt-=i;
                    }
                    if(num.size()==n){
                        flag=1;
                        break;
                    }
                    if(num.size()>n){
                        break;
                    }
                    cnt=y;
                    while(num.size()<n){
                        num.push_back(cnt+i);
                        cnt+=i;
                    }
                    if(num.size()==n){
                        flag=1;
                        break;
                    }
                    if(num.size()>n){
                        break;
                    }
                }
                if(flag)
                    break;
            }
            sort(num.begin(),num.end());
            for(auto x:num){
                cout<<x<<" ";
            }
            cout<<endl;
        }
        return 0;
    }
    View Code

    D题

    答案一定是后面跟着一串0,因此从低位往上做即可

    E题

    枚举+二分+后缀最大值,我们只暴力x,然后排序。

    因为只有两个,因此常见的套路就是枚举第一个做第二个,第一个做了之后,就是找第一个不能覆盖的位置取一个最大值

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=2e5+10;
    const int mod=1e9+7;
    int a[N],b[N];
    vector<int> num;
    map<int,int> m1;
    int d[N];
    int id[N];
    struct node{
        int l,r;
        int mx;
    }tr[N<<2];
    void pushup(int u){
        tr[u].mx=max(tr[u<<1].mx,tr[u<<1|1].mx);
    }
    void build(int u,int l,int r){
        if(l==r){
            tr[u]={l,r,0};
        }
        else{
            tr[u]={l,r};
            int mid=l+r>>1;
            build(u<<1,l,mid);
            build(u<<1|1,mid+1,r);
            pushup(u);
        }
    }
    void modify(int u,int l,int x){
        if(tr[u].l==tr[u].r){
            tr[u].mx+=x;
            return ;
        }
        int mid=tr[u].l+tr[u].r>>1;
        if(l<=mid)
            modify(u<<1,l,x);
        else
            modify(u<<1|1,l,x);
        pushup(u);
    }
    int query(int u,int l,int r){
        if(tr[u].l>=l&&tr[u].r<=r){
            return tr[u].mx;
        }
        int mid=tr[u].l+tr[u].r>>1;
        int ans=0;
        if(l<=mid)
            ans=query(u<<1,l,r);
        if(r>mid)
            ans=max(ans,query(u<<1|1,l,r));
        return ans;
    }
    int main(){
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        while(t--){
            int n,k;
            cin>>n>>k;
            int i;
            m1.clear();
            num.clear();
            for(i=1;i<=n;i++){
                cin>>a[i];
                num.push_back(a[i]);
            }
            for(i=1;i<=n;i++)
                cin>>b[i];
            sort(a+1,a+1+n);
            build(1,1,n+1);
            for(i=1;i<=n;i++){
                if(!m1[a[i]]){
                    m1[a[i]]=i;
                }
            }
            sort(num.begin(),num.end());
            for(i=1;i<=n;i++){
                int x=a[i];
                x+=k;
                if(num[num.size()-1]<x){
                    d[i]=n-i+1;
                    id[i]=n+1;
                }
                int pos=upper_bound(num.begin(),num.end(),x)-num.begin()+1;
                d[i]=pos-i;
                id[i]=pos;
            }
            for(i=1;i<=n;i++){
                modify(1,i,d[i]);
            }
            int ans=0;
            for(i=1;i<=n;i++){
                int x=query(1,id[i],n+1);
                ans=max(ans,d[i]+x);
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    View Code

    F题

    因为要算贡献,且每个位置只有三种变化,不变,变1,变2,因此我们设计状态为前i个,有j个t1,用了k次的最大值

    注意特判t1==t2的情况

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=2e5+10;
    const int mod=1e9+7;
    ll f[210][210][210];
    int main(){
        ios::sync_with_stdio(false);
        string s,t;
        int n,m;
        cin>>n>>m;
        cin>>s>>t;
        int i,j,k;
        s=" "+s;
        t=" "+t;
        memset(f,-0x3f,sizeof f);
        f[0][0][0]=0;
        if(t[1]==t[2]){
            int ans=0;
            for(i=1;i<=n;i++){
                if(s[i]==t[1]){
                    ans++;
                }
            }
            int d=n-ans;
            d=min(m,d);
            ans+=d;
            if(!ans)
                cout<<0<<endl;
            else
                cout<<ans*(ans-1)/2<<endl;
            return 0;
        }
        for(i=1;i<=n;i++){
            for(j=0;j<=i;j++){
                for(k=0;k<=min(m,i);k++){
                    if(s[i]==t[1]){
                        if(j) f[i][j][k]=max(f[i][j][k],f[i-1][j-1][k]);
                        if(k) f[i][j][k]=max(f[i][j][k],f[i-1][j][k-1]+j);
                    }
                    else if(s[i]==t[2]){
                        if(j&&k) f[i][j][k]=max(f[i][j][k],f[i-1][j-1][k-1]);
                        f[i][j][k]=max(f[i][j][k],f[i-1][j][k]+j);
                    }
                    else{
                        f[i][j][k]=f[i-1][j][k];
                        if(k){
                            if(j) f[i][j][k]=max(f[i][j][k],f[i-1][j-1][k-1]);
                            f[i][j][k]=max(f[i][j][k],f[i-1][j][k-1]+j);
                        }
                    }
                }
            }
        }
        ll ans=0;
        for(i=0;i<=n;i++){
            for(j=0;j<=m;j++){
                ans=max(ans,f[n][i][j]);
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    5.不用拷贝的对象可以用ref
    4.bind绑定
    3.bind与仿函数以及普通函数
    35.自己实现vector模板库myvector
    2.boost遍历数组容器
    1.boost库的安装
    34.share_ptr智能指针共享内存,引用计数
    33.unique_ptr独享内存智能指针
    32.智能指针auto_ptr
    131.typename在嵌套类中的作用
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14631165.html
Copyright © 2011-2022 走看看