CodeForces Round 352——Recycling Bottles & Robin Hood

Recycling Bottles
题意:
两个人收废品,一个人一次只能拿一件废品到回收站,然后再出来拿下一个废品。问两个人一共走的距离最少是多少
思路:
因为每次只能拿一个并且后面都是从回收站出来,所以影响距离的就是如何选择第一个废品点。
代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

int ax,ay,bx,by,tx,ty;
int n;
struct Bin{
    double dist;
    double disa;
    double disb;
    int id;
}bin[100005];

bool cmp1(const Bin &a,const Bin &b){
    return a.dist - a.disa > b.dist - b.disa;
}

bool cmp2(const Bin &a,const Bin &b){
    return a.dist - a.disb > b.dist - b.disb;
}

int main()
{
//    freopen("data.txt","r",stdin);
    scanf("%d%d%d%d%d%d",&ax,&ay,&bx,&by,&tx,&ty);
    scanf("%d",&n);
    double sum = 0;
    for(int i = 0; i < n ; ++i){
        int x,y;
        scanf("%d%d",&x,&y);
        bin[i].dist = sqrt((x-tx)*1LL*(x-tx)+(y-ty)*1LL*(y-ty));
        bin[i].disa = sqrt((x-ax)*1LL*(x-ax)+(y-ay)*1LL*(y-ay));
        bin[i].disb = sqrt((x-bx)*1LL*(x-bx)+(y-by)*1LL*(y-by));
        sum += bin[i].dist;
        bin[i].id = i;
    }
    sum *= 2;
    sort(bin,bin+n,cmp1);
    double mina = bin[0].dist - bin[0].disa;
    int ida = bin[0].id;
    double minaa = bin[1].dist - bin[1].disa;
    sort(bin,bin+n,cmp2);
    double minb = bin[0].dist - bin[0].disb;
    int idb = bin[0].id;
    double minbb = bin[1].dist - bin[1].disb;
    if(ida == idb){
        double m = max(minaa+minb,minbb+mina);
        m = max(m,mina);m = max(m,minb);
        sum -= m;
    } else {
        if(mina > 0 && minb >0)sum = sum-mina-minb;
        else sum -= max(mina,minb);
    }
    printf("%.6lf\n",sum);
}

Robin Hood
题意:
一个城市中有一大群人,Robin Hood每次将最富有的一个人的金币拿给最贫穷的一个人。如果财富值相同就随机选取一个。经过k次以后,这个城市最富的跟最穷的金币差是多少

以下翻译官网题解:
我们可以将操作分开进行,先进行所有的增加操作,再进行所有的减少操作。使用下面的算法:
我们要将数组中最小的数加一,这个操作进行k次。可以二分k次操作后的最小值。来看看怎么样确定最小值是大于还是等于p。如果 np=1max(0,pci) 小于等于k,我们就可以把所有的元素加到至少p。这样我们就可以找出k次操作以后可能的最小值。
假设最小值是m,找出m以后我们要把所有比m小的加到m。但是可能有些操作暂时还未进行,未进行的操作数最大是n-1,要不然我们就可以把所有等于m的数加一,这样最小值就不是m了。由于最小的那些数应当相同,我们可以只把等于m的一些数增加。
减操作可以用同样的算法。最后我们打印出最终数组中的 max elementmin element 。总的时间复杂度是 O(nlogk)
我的代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
int n,k;
int c[500005];

int main()
{
//    freopen("data.txt","r",stdin);
    scanf("%d%d",&n,&k);
    ll sum = 0;
    for(int i = 0; i < n;  ++i){
        scanf("%d",&c[i]);
        sum += c[i];
    }
    sort(c,c+n);
    ll avgl = sum/n;
    ll avgr = sum/n + (sum%n ? 1 : 0);
    ll l = c[0];ll r = avgl;
    while(l <= r){
        ll mid = (l+r) >> 1;int tot = k;
        int i;
        for(i = 0; c[i] < mid ; ++i){
            tot -= (mid - c[i]);
            if(tot < 0)break;
        }
        if(tot < 0)r = mid - 1;
        else l = mid + 1;
        if(tot > 0 && tot <= i-1 ){r = mid;break;}
    }
    int mina = r;
    l = avgr;r = c[n-1];
    while(l <= r){
        ll mid = (l+r) >> 1;int tot = k;
        int i;
        for(i = n-1; c[i] > mid ;--i){
            tot -= (c[i] - mid);
            if(tot < 0) break;
        }
        if(tot < 0)l = mid + 1;
//        else if(tot == 0){l = r = mid;break;}
        else r = mid - 1;
        if(tot > 0 && tot <= n-i-2 ){l = mid;break;}
    }
    int minb = l;
    printf("%d\n",minb - mina);
    return 0;
}
发布了267 篇原创文章 · 获赞 12 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/u010734277/article/details/51499308
今日推荐