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

 

posted @ 2021-04-08 10:48  朝暮不思  阅读(58)  评论(0编辑  收藏  举报