zoukankan      html  css  js  c++  java
  • Codeforces Round #592 (Div. 2) 补题记录

    C

    • 题意: n场比赛,总共p分,w为胜利一场的得分,d为平局的得分,求胜利,平局,失败的场数
    • 思路: 因为d次胜利与w次平局所得的分是一样的,假如平局次数超过w次则可以将其转换成d次胜利(w>d所以一定可以转化),枚举到1e5就行了...

    D

    • 题意: 树上染色,共有三种颜色且所有相邻三个点颜色不能重复,每个点染不同颜色有不同的值,求最小值且合法的染色方案
    • 思路: 首先树必须是条链,然后枚举前三个点的全排列就可以确定后面点的颜色,求最小值即可(写了个dp调了我半小时QAQ).
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    
    const int N = 1e5+10;
    
    int n;
    vector<int> cost[3];
    vector<vector<int> > adj;
    vector<int> p,perm ={0,1,2},best_perm,ans;
    int main(){
        ios::sync_with_stdio(0);cin.tie(0);
        int u,v,root;
        cin >> n;
        for(int i=0;i<3;++i){
            cost[i].resize(n);
            for(int j=0;j<n;++j)    cin >> cost[i][j];
        }
        adj.assign(n,{});
        for(int i=0;i<n-1;++i){
            cin >> u >> v;
            u--;    v--;
            adj[u].push_back(v);
            adj[v].push_back(u);
        }
        for(int i=0;i<n;++i){
            if(adj[i].size()>2){
                cout <<"-1
    ";
                return 0;
            }else if(adj[i].size()==1){
                root = i;
            }
        }
        p.push_back(root);
        while(p.size()<n){
            v = p.back();
            for(auto nx:adj[v]){
                if(p.size()==1 ||  nx != p[p.size()-2]){
                    p.push_back(nx);
                    break;
                }
            }
        }
        ll best = 1LL<<62;
        do{
            ll score = 0;
            for(int i=0;i<n;++i)    score += cost[perm[i%3]][p[i]];
            if(score<best){
                best_perm = perm;
                best = score;
            }
        }while(next_permutation(perm.begin(),perm.end()));
        cout << best << '
    ';
        ans.resize(n);
        for(int i=0;i<n;++i)    ans[p[i]] = best_perm[i%3];
        for(int i=0;i<n;++i)    cout << ans[i]+1<<' ';
        cout <<'
    ';
        return 0;
    }
    

    E

    • 题意: 一个序列,每次可以选一个数+1或-1,可以操作k次,求最小化最大减最小的差.
    • 思路: 二分差,肯定有一个a[i]是不变的,check时就枚举a[i]不变(上界下界枚举两次),然后lower_bound找到比下界小的,要加到下界,upper_bound找到比上界大的,要减到上界,算操作次数是否满足小于k.
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
     
    const int N = 1e5+10;
     
    ll n,k;
    ll a[N],sum[N];
     
    bool check(int d){
        for(int i=1;i<=n;++i){
            int low = lower_bound(a+1,a+1+n,a[i])-a-1;
            int hgh = upper_bound(a+1,a+1+n,a[i]+d)-a;
            ll tot = 1LL*low*a[i] - sum[low] + sum[n] - sum[hgh-1] - 1LL*(n-hgh+1)*(a[i]+d);
            if(tot <=k) return true;
        }
        for(int i=1;i<=n;++i){
            int hgh = upper_bound(a+1,a+1+n,a[i])-a;
            int low = lower_bound(a+1,a+1+n,a[i]-d)-a-1;
            ll tot = 1LL*low*(a[i]-d) - sum[low] + sum[n] - sum[hgh-1] - 1LL*(n-hgh+1)*a[i];
            if(tot <=k) return true;
        }
        return false;
    }
    int main(){
        cin >> n >> k;
        for(int i=1;i<=n;++i) cin >> a[i];
        sort(a+1,a+1+n);
        for(int i=1;i<=n;++i)   sum[i] = sum[i-1] + a[i];
        int l = 0,r = 1e9;
        int mid,ans = -1;
        while(l<=r){
            mid = (l+r)>>1;
            if(check(mid)){
                ans = mid;
                r = mid-1;
            }else{
                l = mid+1;
            }
        }
        cout << ans << endl;
        return 0;
    }
    
    

    这几天训练莫得动力,再不加大力度自己要莫得了

  • 相关阅读:
    finalshell连接工具
    oracle11g R2数据库的迁移(同windows系统迁移)使用RMAN
    《python可以这样学》第一章
    python环境开发
    HTTP下帐号密码的截取
    Kail Linux下载与安装
    查看Linux系统内存、CPU、磁盘使用率和详细信息
    内网获取目标的浏览过的所有图片
    修改kali软件源并配置网络
    Python迭代器与生成器
  • 原文地址:https://www.cnblogs.com/xxrlz/p/11682009.html
Copyright © 2011-2022 走看看