zoukankan      html  css  js  c++  java
  • 【Codeforce】 #643 div2

    传送门

    A. Sequence with Digits

    题意

    给定(a,k), 每次使得(a)进行如下计算:

    [a_{n+1}=a_{n}+min operatorname{Digit}left(a_{n} ight) cdot max operatorname{Digit}left(a_{n} ight) ]

    (k)次计算后的值

    数据范围

    (1 leq a_{1} leq 10^{18}, 1 leq K leq 10^{16})

    题解

    在一定次数的计算后,出现0就不会改变了,直接break

    Code

    cpp
    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,n) for(int i=a;i<n;i++)
    #define per(i,a,n) for(int i=n-1;i>=a;i--)
    #define ll long long
    int _;
    int main(){
        for(scanf("%d",&_);_;_--){
            ll a,k;
            cin>>a>>k;
            bool flag=1;
            k--;
            while(k-- && flag){
                ll t=a;
                ll mn=1e18,mx=0;         
                while(t){
                    ll x=t%10;
                    //if(x==0) {flag=0;break;}
                    t/=10;
                    mn=min(mn,x);
                    mx=max(mx,x);
                }
                if(mn==0 || mx==0) break;
                a+=mn*mx;
            }
            cout<<a<<endl;
        }
    }
    

    B. Young Explorers

    题意

    给定(N)个人,每个人有一个经验值(e),每个人只能存在于人数大于等于他经验值得队,求出可以分配的最大的队伍

    数据范围

    (1 leq N leq 2 cdot 10^{5})
    (1 leq e_{i} leq N)

    题解

    从小到大贪心,贪心的策略是不多分配,可以分配一个群组就分配恰好的数量,
    维护一个当前的人数即可,
    存在一个单调性,即当前人之前剩下的人数一定不会大于当前人的经验值

    Code

    cpp
    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,n) for(int i=a;i<n;i++)
    #define per(i,a,n) for(int i=n-1;i>=a;i--)
    #define ll long long
    int _;
    const int N=2e5+10;
    int e[N];
    int main(){
        for(scanf("%d",&_);_;_--){
            unordered_map<int,int>p;
            set<int>s;
            int n;
            scanf("%d",&n);
            rep(i,0,n) {int x;scanf("%d",&x); p[x]++; s.insert(x);}
            int now=0;
            int ans=0;
            for(auto it:s){
                now+=p[it];
                if(it <= now) {
                    ans+=now/it;
                    now-=(now/it * it); 
                }
            }
            printf("%d
    ",ans);
        }
    }
    

    C. Count Triangles

    题意

    给定(A,B,C,D)求一个三角形的三边(x,y,z),满足(A leq xleq B leq yleq Cleq z leq D),求在合法范围内能构成多少种三角形

    数据范围

    (1 leq A leq x leq Bleq y leq C leq zleq D leq10^{5})

    题解

    用较小的两边之和(sum)大于第三边判断三角形是否合法,枚举小的两边和, 求出在合法的范围内第三条边的个数为(min(D , sum-1) - C +1)
    再求出两条边的和为(i)的个数,

    [ecause x+y=sum ]

    [ herefore y=sum-x ]

    [ecause B leq y leq C ]

    [ herefore B leq sum-x leq C ]

    [ herefore sum-C leq x leq sum-B为和为x+y的x和y的个数 ]

    Code

    cpp
    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,n) for(int i=a;i<n;i++)
    #define per(i,a,n) for(int i=n-1;i>=a;i--)
    #define ll long long
    int main(){
        ll a,b,c,d;
        cin>>a>>b>>c>>d;
        ll ans=0;
        for(ll i=a+b;i<=b+c;i++){
            ll z=min(d,i-1)-c+1,t=min(i-b,b)-max(i-c,a)+1;
            if(z<0 || t<0) continue;
            ans+=z * t;
        }
        cout<<ans<<endl;
    }
    

    D. Game With Array

    题意

    构造一个数组长度为(N),和为(S) 的数组,一个(K), 问是否能构造出使得所有的子序列和不等于(K)(S-K)

    数据范围

    (1leq Nleq Sleq 10^{6})
    (0 leq K leq S)

    题解

    (n-1)全填(2),剩下的如果(leq 1)则无法构造出,否则只要选择(K=1)即可

    Code

    cpp
    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,n) for(int i=a;i<n;i++)
    #define per(i,a,n) for(int i=n-1;i>=a;i--)
    #define ll long long
    int main(){
        int n,s;
        cin>>n>>s;
        int s_=s-(n-1)*2;
        if(s_<=1){puts("NO");return 0;}
    
        vi ans;
        rep(i,0,n-1) ans.pb(2);
        ans.pb(s_);
        puts("YES");
        for(auto it: ans)
            cout<<it<<' ';
        puts("");
        cout<<"1"<<endl;
    }
    

    E. Restorer Distance

    题意

    给定(N)堆盘的高度(h_{i}),三个操作,

    • 添加一个到一个的最上面代价(A)
    • 移除一个最上面的代价(B)
    • 将一个的最上面的移动到另一个上代价(M)

    求出让所有的堆高度相同的最小代价

    数据范围

    (1leq N leq 10^{5})
    (0 leq h_{i} leq 10^{9})
    $ 0 leq A, R, M leq 10^{4}$

    题解

    首先可以将(M)换成(min(M,A+B)),可以看出来代价关于高度h是一个单谷函数,因此三分求最小值

    Code

    cpp
    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,n) for(int i=a;i<n;i++)
    #define per(i,a,n) for(int i=n-1;i>=a;i--)
    #define fi first
    #define se second 
    #define ll long long
    #define pb push_back
    typedef pair<long long,long long> pll;
    typedef pair<int,int> pii;
    typedef vector<int> vi;
    typedef vector<long long> vll;
    typedef double db;
    const ll mod=1e9+7;
    ll powmod(ll a,ll b,ll p){ll res=1;a%=p;while(b){if(b&1) res=res*a%p;a=a*a%p;b>>=1;}return res;}
    ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
    const int N=1e5+10;
    ll h[N];
    ll n,a,r,m;
    ll cal(ll x){
        ll add=0,del=0;
        for(int i=0;i<n;i++) {
            if(h[i]>x) del+=h[i]-x;
            if(h[i]<x) add+=x-h[i];
        }
        ll delta=abs(del-add),move=min(del,add);
        ll res=0;
        res+=move*m;
        if(del>add) res+=delta*r;
        if(add>del) res+=delta*a;
        return res;
    }
    int main(){
        cin>>n>>a>>r>>m;
        m=min(m,a+r);
        for(int i=0;i<n;i++) cin>>h[i];
        ll l=0,r=1e9;
        while(l<r){
            ll lmid=(l*2+r)/3,rmid=(r*2+l+2)/3;
            if(cal(lmid)<cal(rmid)) r=rmid-1;
            else l=lmid+1;
        }
        cout<<cal(l)<<endl;
    }
    
  • 相关阅读:
    poj 2112
    写给学大计python的同学的查错方法
    [Win32 API学习] Edit,ListBox的用法,字体的设置
    [Win32 API] FindFirstFile()和FindNextFile()
    初探C++ win32 api——Hello world!
    [学习笔记]舞蹈链(DLX)(C++指针版)
    2020科大回归记
    SCOI2019AFO记
    [学习笔记]动态动态规划/动态DP/DDP
    BZOJ5343[CTSC2018]混合果汁(二分答案+主席树)
  • 原文地址:https://www.cnblogs.com/hhyx/p/12925350.html
Copyright © 2011-2022 走看看