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

    A题

    找两两比列,按2的次幂进行划分

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> pll;
    const int N=1e5+200;
    const int mod=1e9+7;
    int a[N];
    int main(){
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        while(t--){
            int n;
            cin>>n;
            int i;
            for(i=1;i<=n;i++){
                cin>>a[i];
            }
            int ans=0;
            for(i=1;i<n;i++){
                int x=max(a[i],a[i+1]);
                int y=min(a[i],a[i+1]);
                int d=x/y;
                if(x%y)
                    d++;
                int tmp=0;
                for(int j=1;j<10;j++){
                    if(pow(2,j)<d){
                        tmp++;
                    }
                    else{
                        break;
                    }
                }
                ans+=tmp;
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    View Code

    B题

    暴力做,我们发现每个位置的数相同,因此模拟增量,从mod 0开始计算差值,之后进行平移

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> pll;
    const int N=1e5+200;
    const int mod=1e9+7;
    int a[N];
    int cnt[5];
    int main(){
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        while(t--){
            int n;
            cin>>n;
            int i;
            for(i=1;i<=n;i++){
                cin>>a[i];
            }
            for(i=0;i<3;i++)
                cnt[i]=0;
            for(i=1;i<=n;i++){
                if(a[i]%3==0)
                    cnt[0]++;
                if(a[i]%3==1)
                    cnt[1]++;
                if(a[i]%3==2)
                    cnt[2]++;
            }
            int x=n/3;
            int ans=0;
            if(cnt[0]<x){
                cnt[2]-=(x-cnt[0]);
                ans+=(x-cnt[0]);
            }
            else{
                cnt[1]+=(cnt[0]-x);
                ans+=(cnt[0]-x);
            }
            if(cnt[1]<x){
                ans+=(x-cnt[1])*2;
            }
            else{
                ans+=(cnt[1]-x);
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    View Code

    C题

    模拟题,因为开三次方的大小不会太大,因此枚举每个平方数计算

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> pll;
    const int N=1e5+200;
    const int mod=1e9+7;
    ll a[N];
    map<ll,int> m1;
    int main(){
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        for(ll i=1;i<=10000;i++){
            a[i]=i*i*i;
            m1[a[i]]++;
        }
        while(t--){
            ll x;
            cin>>x;
            int flag=0;
            for(int i=1;i<=10000;i++){
                if(m1[x-a[i]]){
                    flag=1;
                    break;
                }
            }
            if(flag){
                cout<<"YES"<<endl;
            }
            else{
                cout<<"NO"<<endl;
            }
        }
        return 0;
    }
    View Code

    D题

    模拟建树,01位置分别代表左右子树,log跳跃,记录每个位置的pos,从根节点开始,根据相对位置跳转

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> pll;
    const int N=1e5+200;
    const int mod=1e9+7;
    int a[N];
    int g[200][200];
    int pos[N],depth[N];
    void dfs(int u,int fa){
        depth[u]=depth[fa]+1;
        for(int i=0;i<=1;i++){
            int j=g[u][i];
            if(j==0)
                continue;
            dfs(j,u);
        }
    }
    int main(){
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        while(t--){
            int n;
            cin>>n;
            int i;
            for(i=1;i<=n;i++){
                cin>>a[i];
                pos[a[i]]=i;
                g[i][0]=g[i][1]=0;
            }
            int rt=n;
            depth[rt]=1;
            for(i=n-1;i>=1;i--){
                int tmp=rt;
                while(1){
                    if(pos[i]<pos[tmp]){
                        if(g[tmp][0]){
                            tmp=g[tmp][0];
                        }
                        else{
                            g[tmp][0]=i;
                            break;
                        }
                    }
                    else{
                        if(g[tmp][1]){
                            tmp=g[tmp][1];
                        }
                        else{
                            g[tmp][1]=i;
                            break;
                        }
                    }
                }
            }
            dfs(rt,0);
            for(i=1;i<=n;i++){
                cout<<depth[a[i]]-1<<" ";
            }
            cout<<endl;
        }
        return 0;
    }
    View Code

    E题

    对于一个人最优解就是把比他小的全吃完再往后比,因此记录一个前缀和,找到最后一个前缀和不能大于后一个数的位置,后面的大小都可以

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> pll;
    const int N=2e5+200;
    const int mod=1e9+7;
    int a[N],b[N];
    map<int,int> m1;
    int sign[N];
    int main(){
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        while(t--){
            int n;
            cin>>n;
            int i;
            m1.clear();
            for(i=1;i<=n;i++){
                cin>>a[i];
                sign[i]=0;
                b[i]=a[i];
            }
            sort(a+1,a+1+n);
            ll sum=0;
            for(i=1;i<n;i++){
                sum+=a[i];
                if(sum<a[i+1]){
                    sign[i]=1;
                }
            }
            for(i=n;i>=1;i--){
                if(sign[i])
                    break;
                m1[a[i]]=1;
            }
            cout<<n-i<<endl;
            for(i=1;i<=n;i++){
                if(m1[b[i]]){
                    cout<<i<<" ";
                }
            }
            cout<<endl;
        }
        return 0;
    }
    View Code

    F题

    类似差分数组的思想,维护前缀后缀,这样枚举C,前面的变成0,后面的变成C即可

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> pll;
    const int N=2e5+200;
    const int mod=1e9+7;
    int a[N];
    ll pre[N],suf[N],d[N];
    map<ll,int> m1;
    int main(){
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        while(t--){
            int n;
            cin>>n;
            int i;
            m1.clear();
            for(i=1;i<=n;i++){
                cin>>a[i];
                m1[a[i]]++;
                pre[i]=suf[i]=d[i]=0;
            }
            suf[n+1]=0;
            d[n+1]=0;
            int cnt=0;
            for(auto x:m1){
                pre[x.second]+=x.second;
                suf[x.second]+=x.second;
                d[x.second]+=1;
            }
            for(i=1;i<=n;i++){
                pre[i]+=pre[i-1];
            }
            for(i=n;i>=1;i--){
                suf[i]+=suf[i+1];
            }
            for(i=n;i>=1;i--){
                d[i]+=d[i+1];
            }
            ll ans=1e9;
            for(i=1;i<=n;i++){
                //cout<<pre[i-1]<<" "<<suf[i+1]<<" "<<d[i]*i<<endl;
                ans=min(ans,pre[i-1]+suf[i+1]-d[i+1]*i);
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    View Code

    G题

    一大圈的贡献是相等的,用map的lower_bound进行二分查找分类讨论即可

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<ll,ll> pll;
    const int N=2e5+200;
    const int mod=1e9+7;
    ll a[N];
    map<ll,ll> m1;
    int main(){
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        while(t--){
            ll n,m;
            cin>>n>>m;
            m1.clear();
            int i;
            ll row=0,mx=0,mxid=0;
            for(i=1;i<=n;i++){
                cin>>a[i];
                row+=a[i];
                if(row>mx){
                    mx=row;
                    mxid=i;
                    m1[mx]=i;
                }
            }
            for(i=1;i<=m;i++){
                ll x;
                cin>>x;
                auto it=m1.lower_bound(x);
                if(it==m1.end()&&row<=0){
                    cout<<-1<<" ";
                    continue;
                }
                else if(it==m1.end()){
                    auto lst=m1.end();
                    --lst;
                    int nd=(x-lst->first+row-1)/row;
                    it=m1.lower_bound(x-nd*row);
                    cout<<it->second+nd*n-1<<" ";
                }
                else{
                    cout<<it->second-1<<" ";
                }
     
            }
            cout<<endl;
        }
        return 0;
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    BZOJ 1726: [Usaco2006 Nov]Roadblocks第二短路
    BZOJ 1708: [Usaco2007 Oct]Money奶牛的硬币
    BZOJ 1642: [Usaco2007 Nov]Milking Time 挤奶时间
    BZOJ 1611: [Usaco2008 Feb]Meteor Shower流星雨
    BZOJ 1610: [Usaco2008 Feb]Line连线游戏
    BZOJ 1609: [Usaco2008 Feb]Eating Together麻烦的聚餐
    BZOJ 1607: [Usaco2008 Dec]Patting Heads 轻拍牛头
    BZOJ 1606: [Usaco2008 Dec]Hay For Sale 购买干草
    BZOJ 1083: [SCOI2005]繁忙的都市
    STL set的用法
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14410213.html
Copyright © 2011-2022 走看看