• Codeforces Round #407 div2 题解【ABCDE】


    Anastasia and pebbles

    题意:你有两种框,每个框可以最多装k重量的物品,但是你每个框不能装不一样的物品。现在地面上有n个物品,问你最少多少次,可以把这n个物品全部装回去。

    题解:其实就是问你得用多少次框,然后把多少次除以2就好了。每次装k的物品装回去就好了。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5+7;
    int a[maxn],n,k;
    int main(){
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
            cin>>a[i];
        sort(a+1,a+1+n);
        long long ans = 0;
        for(int i=1;i<=n;i++){
            ans+=(a[i]+k-1)/k;
        }
        cout<<(ans+1)/2LL<<endl;
    }
    

    Masha and geometric depression

    题意:给你一个b1,q,再给你一个l,m,和m个数a[i]。然后你需要把不等于a[i],且小于等于l的数记录下来。

    题解:直接暴力就好了,因为等比数列跑得特别快,如果要超过l的话,会很快的超过l了,而且如果答案有限的话,显然不会超过200?所以直接暴力吧。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    set<long long> S;
    long long b,q,l,m;
    map<long long,int>H;
    int main(){
        cin>>b>>q>>l>>m;
        for(int i=0;i<m;i++){
            long long k;
            cin>>k;
            S.insert(k);
        }
        int time = 0;
        int ans = 0;
        long long now = b;
        while(time<500000){
            time++;
            if(abs(now)>l)break;
            if(S.find(now)==S.end()){
                ans++;
            }
            now=now*q;
        }
        if(ans>30000){
            cout<<"inf"<<endl;
        }else{
            cout<<ans<<endl;
        }
    }
    

    Functions again

    题意:定义f(l,r)=sigma(abs(a[i]-a[i+1)*(-1)^(i-l)),给你n个数,找到最大的f(l,r)

    题解:跑一个前缀和,然后你要奇数位置开头的,那么就正常做。如果是偶数位置开始的话,那么就乘上一个-1就好了嘛。掏个set算前缀的最小值和最大值。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5+7;
    long long a[maxn],b[maxn],c[maxn];
    int n;
    set<long long>A,B;
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            cin>>a[i];
        if(n==2){
            cout<<abs(a[1]-a[2])<<endl;
            return 0;
        }
        for(int i=1;i<n;i++){
            b[i]=abs(a[i]-a[i+1]);
            if(i%2==1)c[i]=c[i-1]+b[i];
            else c[i]=c[i-1]-b[i];
        }
        A.insert(c[1]);
        B.insert(c[2]);
        long long ans = max(c[1],c[2]);
        ans=max(ans,abs(a[2]-a[3]));
        for(int i=3;i<n;i++){
            ans=max(ans,c[i]);
            ans=max(ans,c[i]-*B.begin());
            ans=max(ans,c[i]-*--B.end());
            ans=max(ans,-(c[i]-*A.begin()));
            ans=max(ans,-(c[i]-*--A.end()));
            if(i%2==1)A.insert(c[i]);
            else B.insert(c[i]);
        }
        cout<<ans<<endl;
    }
    

    D. Weird journey

    题意: 给你一个图,这个图有自环,现在问你有多少个路径满足可以经过m-2条边两次,剩下两条边一次。

    题解:答案为 自环与自环相组合,自环和其他边组合,其他边和其他边组合。其中其他边和其他边组合的时候,必须要挨在一起。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e6+7;
    int n,m;
    vector<int>E[maxn];
    int Cnt,flag[maxn],vis[maxn],d[maxn];
    void dfs(int x){
        vis[x]=1;
        for(int i=0;i<E[x].size();i++){
            Cnt++;
            if(E[x][i]==0){
                Cnt++;
                continue;
            }
            if(vis[E[x][i]])continue;
            dfs(E[x][i]);
        }
    }
    int main(){
        scanf("%d%d",&n,&m);
        int st = 1,cnt = 0,cnt2 = 0;
        for(int i=0;i<m;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            if(a==b){
                cnt ++;
                flag[a]++;
                E[a].push_back(0);
                E[0].push_back(a);
            }else{
                st=a;
                cnt2++;
                d[a]++;d[b]++;
                E[a].push_back(b);
                E[b].push_back(a);
            }
        }
        dfs(st);
        if(Cnt!=m*2){
            cout<<"0"<<endl;
            return 0;
        }
        long long ans = 0;
        ans=ans+1ll*cnt*cnt2;
        ans=ans+1ll*cnt*(cnt-1)/2;
        for(int i=1;i<=n;i++){
            ans=ans+1ll*d[i]*(d[i]-1)/2;
        }
        cout<<ans<<endl;
    }
    

    E. The Great Mixing

    题意:现在有k个物品xi/1000,你现在可以任意挑选,并随便使用,你需要调制出n/1000的物品,问你最少使用多少个。

    题解:首先去重,那么k最多只有1001了。然后我们让所有的xi减去n,然后就可以理解为凑0了,然后就可以跑完全背包。第一维的个数最多1000个,第二维的范围就是[-1000,1000]。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    int n,k;
    const int maxn = 1e6+7;
    int a[maxn];
    vector<int>v;
    map<int,int> dp[2003];
    int main(){
        scanf("%d%d",&n,&k);
        for(int i=1;i<=k;i++){
            scanf("%d",&a[i]);
            a[i]-=n;
            v.push_back(a[i]);
        }
        sort(v.begin(),v.end());
        v.erase(unique(v.begin(),v.end()),v.end());
        dp[0][0]=1;
        map<int,int>::iterator it;
        for(int i=1;i<=1002;i++){
            for(it=dp[i-1].begin();it!=dp[i-1].end();it++){
                for(int j=0;j<v.size();j++){
                    if(abs(it->first+v[j])>1000)continue;
                    dp[i][it->first+v[j]]=1;
                }
            }
            if(dp[i].count(0)){
                printf("%d
    ",i);
                return 0;
            }
        }
        printf("-1
    ");
        //ax+by+...+t=n*1000(a+b+c+..+);
    }
  • 相关阅读:
    The C++ Source A Pause to Reflect: Five Lists of Five, Part I The Most Important C++ Books...Ever
    Cg 1.5 Released
    Half Life 2 Source 引擎介绍
    一大清早去飙车
    [旧闻一]NVIDIA招揽前Intel顶级CPU设计师
    [旧闻二]AMD收购ATI
    【翻译】[Effective C++第三版•中文版][第17条]要在单独的语句中使用智能指针来存储由new创建的对象
    Generic:简化异常安全代码
    第29条: 力求使代码做到“异常安全”
    Linux压缩打包命令使用方法
  • 原文地址:https://www.cnblogs.com/qscqesze/p/6643944.html
Copyright © 2020-2023  润新知