zoukankan      html  css  js  c++  java
  • Wannafly挑战赛15

    标签: nowcoder


    传送门

    https://www.nowcoder.com/acm/contest/112#question

    A.最小化价格

    贪心做的。贪心策略:从价格最低的开始分配,然后对于每个地点把它所能容纳的最大的队伍分配给他。(PS:看到钰神的贪心策略是这样的,从人数最多的队伍开始分配,每次把能够容纳这个队伍的价格最低的分配给他,优先队列就可以实现)

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <cstdio>
    #include <map>
    #include <unordered_map>
    using namespace std;
    const int maxn=200050;
    typedef long long ll;
    const ll MOd=1e9+7;
    struct node{
        int x,p;
        bool operator <(const node&y)const{
            if(p!=y.p) return p<y.p;
            return x>y.x;
        }
    }b[maxn];
    int a[maxn];
    bool cmp(int a,int b){
        return a>b;
    }
    map<int,int> mp;
    int main(){
        int n,m;
        scanf("%d%d", &n,&m);
        int M=0;
        for(int i = 0; i < n; ++i){
            int x;
            scanf("%d", &x);
            M=max(M,x);
            mp[x]++;
        }
        for(int i = 0; i < m; ++i){
            scanf("%d%d", &b[i].x,&b[i].p);
        }
        sort(b,b+m);
        int sum=0;
        for(int i = 0; i < m; ++i){
            map<int,int>::iterator it=mp.lower_bound(b[i].x);
            if(it->first == b[i].x) it->second --,sum+=b[i].p;
            else if(it==mp.begin()) continue;
            else{
                it--;
                it->second --;
                sum+=b[i].p;
            }
            if(it->second == 0){
                mp.erase(it);
            }
        }
        if(mp.size()) cout << -1 << endl;
        else cout << sum << endl;
    }
    

    B.车辆安排

    #include <iostream>
    #include <cstdio>
    using namespace std;
    int a[10];
    int main(){
        int n;
        scanf("%d", &n);
        for(int i = 0; i < n; ++i){
            int x;
            scanf("%d", &x);
            a[x]++;
        }
        int ans=a[5];
        if(a[1]>a[4]) a[1]-=a[4],ans+=a[4],a[4]=0;
        else a[1]=0,ans+=a[4],a[4]=0;
        if(a[2]>a[3]) a[2]-=a[3],ans+=a[3],a[3]=0;
        else{
            ans+=a[2],a[3]-=a[2],a[2]=0;
            if(a[1]>2*a[3]) ans+=a[3],a[1]-=2*a[3],a[3]=0;
            else ans+=a[3],a[1]=0,a[3]=0;
        }
        if(2*a[1]<a[2]){
            ans+=a[1];
            a[2]-=a[1]*2;
            a[1]=0;
        }
        else{
            ans+=a[2]/2;
            a[1]-=a[2]/2;
            a[2]-=a[2]/2*2;
        }
        if(a[2]&&a[1]==0){
            ans+=(a[2]+1)/2;
        }
        else{
            int x=a[1]+a[2]*2;
            ans+=(x/5);
            if(x%5) ans++;
        }
        cout << ans <<endl;
    }
    

    C.出队

    递归模拟即可,时间复杂度(O(log_2x))

    #include <iostream>
    #include <cstdio>
    using namespace std;
    typedef long long ll;
    ll f(ll n,ll x){
        if(x&1) return (x+1)/2;
        ll y=x/2-1;
        if(y==0) y=n/2;
        if(n&1) return n/2+1+f(n/2,y);
        return n/2+f(n/2,x/2);
    }
    int main(){
        ll n,q;
        scanf("%lld%lld", &n,&q);
        while(q--){
            ll x;
            scanf("%lld", &x);
            cout << f(n,x) << endl;
        }
        return 0;
    }
    

    D.数字串

    对于每个数字都建立一个树状数组,每次修改时先减去他的影响,再加上新数的影响。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    typedef long long ll;
    const int maxn=100050;
    int a[10][maxn],n;
    void update(int *p,int x,int val){
        while(x<=n){
            p[x]+=val;
            x += x&-x;
        }
    }
    int query(int *p,int x){
        int ans=0;
        while(x){
            ans+=p[x];
            x-=x&-x;
        }
        return ans;
    }
    char s[maxn];
    int main(){
        scanf("%s", s+1);
        n=strlen(s+1);
        int q,l,r;
        scanf("%d%d%d", &q,&l,&r);
        ll sum=0;
        for(int i = n; i >= 1; --i){
            update(a[s[i]-'0'],i,1);
            for(int j = 0; j < s[i]-'0'; ++j){
                sum+=query(a[j],min(i+r-1,n))-query(a[j],min(n,i+l-2));
            }
        }
        while(q--){
            int i,x;
            scanf("%d%d", &i,&x);
            int y=s[i]-'0';
            s[i]=x+'0';
            for(int j = 0; j < y; ++j){
                sum-=query(a[j],min(i+r-1,n))-query(a[j],min(n,i+l-2));
            }
            for(int j = 9; j > y; --j){
                sum-=query(a[j],max(i-l+1,0))-query(a[j],max(0,i-r));
            }
            update(a[y],i,-1);
            for(int j = 0; j < x; ++j){
                sum+=query(a[j],min(i+r-1,n))-query(a[j],min(n,i+l-2));
            }
            for(int j = 9; j > x; --j){
                sum+=query(a[j],max(i-l+1,0))-query(a[j],max(0,i-r));
            }
            update(a[x],i,1);
            printf("%lld
    ", sum);
        }
        return 0;
    }
    

    E.小W的斜率

    分析

      我们要求两个点连线斜率最接近(P/Q)的。可以考虑这样,在((Q,P))方向和((P,-Q))建立新的坐标轴,那么沿着((P,-Q))方向排列所有的点,排列后相邻的点之间的连线的斜率一定是最接近(P/Q)的。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
     
    using namespace std;
    typedef long long ll;
    const ll MOD=1e9+7;
    const int maxn=1000050;
    int n,p,q;
    struct node{
        int x,y;
        bool operator < (const node&t)const{
            return (ll)p*x-(ll)q*y<(ll)p*t.x-(ll)q*t.y;
        }
    }a[maxn];
    int main(){
        scanf("%d%d%d", &n,&p,&q);
        for(int i = 0; i < n; ++i) scanf("%d%d", &a[i].x,&a[i].y);
        sort(a,a+n);
        double m=1e20;
        int P,Q;
        for(int i = 1; i < n; ++i){
            double t=(double)(a[i].y-a[i-1].y)/(double)(a[i].x-a[i-1].x)-(double)p/q;
            if(fabs(t)<m){
                m=fabs(t);
                P=a[i].y-a[i-1].y;
                Q=a[i].x-a[i-1].x;
            }
        }
        
        if(P<0) P=-P,Q=-Q;
        int d=__gcd(P,Q);
        P/=d,Q/=d;
        printf("%d/%d
    ", P,Q);
    }
    

    F.下棋

    留坑

  • 相关阅读:
    cf B. Sereja and Suffixes
    cf E. Dima and Magic Guitar
    cf D. Dima and Trap Graph
    cf C. Dima and Salad
    最短路径问题(floyd)
    Drainage Ditches(网络流(EK算法))
    图结构练习—BFSDFS—判断可达性(BFS)
    Sorting It All Out(拓扑排序)
    Power Network(最大流(EK算法))
    Labeling Balls(拓扑)
  • 原文地址:https://www.cnblogs.com/sciorz/p/9030442.html
Copyright © 2011-2022 走看看