Codeforces Round #352 (Div. 2) C D

Codeforces Round #352 (Div. 2) C. Recycling Bottles


题目链接:点这里!!!!


题意:

A、B两个人的任务负责把地图上的n个垃圾放到垃圾桶里,每次只能捡一个垃圾,将其放到垃圾桶里之后再去捡其他的垃圾,问你两个人总共走的路程最短为多少。

给出A、B、垃圾桶的坐标 (ax,ay)(bx,by)(tx,ty),再给你n(n<=1e5)个垃圾的坐标(x[i],y[i]),所有坐标0<=x<=1e9,0<=y<=1e9。


题解:

最后一秒提交,然而还是没过終测,QWQ太弱了。


1、我们假定A、B初始在垃圾桶的位置(tx,ty)。我们可以求出垃圾桶到所有垃圾的位置的距离为d[1],d[2],d[3]...d[n],设sum=d[1]+d[2]+...d[n],这种情况的答案为2*sum。


2、但是(ax,ay)、(bx、by)并不在(tx,ty)我们可以做差值来取最优。假设a[i]为A点第i个垃圾的距离-d[i](相当于能优化多少时间)。b[i]也是相同的道理。


3、然后我们将a[i]、b[i]分别按从小到大排序。取出a[0],a[1];b[0],b[1]。然后进行比较,取最优就可以。注意A,B不能取同一个垃圾,这里判断一下;还要注意比较A一个人捡垃圾所走的路程,还有B一个人捡垃圾所走的路程(你可以想象A在北京,B在美国,垃圾都离B很近,B一个人捡就可以了)。



代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<sstream>
#include<algorithm>
#include<vector>
#include<bitset>
#include<set>
#include<queue>
#include<stack>
#include<map>
#include<cstdlib>
#include<cmath>
#define PI 2*asin(1.0)
#define LL long long
#define pb push_back
#define pa pair<int,int>
#define clr(a,b) memset(a,b,sizeof(a))
#define lson lr<<1,l,mid
#define rson lr<<1|1,mid+1,r
#define bug(x) printf("%d++++++++++++++++++++%d\n",x,x)
#define key_value ch[ch[root][1]][0]C:\Program Files\Git\bin
const LL  MOD = 1000000007;
const LL N = 1e5+15;
const int maxn = 1e6+15;
const int letter = 130;
const LL INF = 1e18;
const double pi=acos(-1.0);
const double eps=1e-10;
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int ax,ay,bx,by,tx,ty,n;
int x[N],y[N];
int vis[N];
long double ok(int x1,int y1,int x2,int y2){
    return sqrt(1.0*(x1-x2)*(x1-x2)+1.0*(y1-y2)*(y1-y2));
}
struct node{
    long double val;
    int id;
    bool operator <(const node &p)const{
        return val<p.val;
    }
}a[N],b[N];
int main(){
    scanf("%d%d%d%d%d%d",&ax,&ay,&bx,&by,&tx,&ty);
    scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%d%d",x+i,y+i);
    for(int i=0;i<n;i++){
        a[i].val=ok(ax,ay,x[i],y[i])-ok(x[i],y[i],tx,ty);
        b[i].val=ok(bx,by,x[i],y[i])-ok(x[i],y[i],tx,ty);
        a[i].id=i;
        b[i].id=i;
    }
    sort(a,a+n);
    sort(b,b+n);
    long double sum=0;
    long double min1=INF;
        if(a[0].id!=b[0].id){
            vis[a[0].id]=vis[b[0].id]=1;
            sum=a[0].val+b[0].val;
        for(int i=0;i<n;i++){
                sum+=2.0*ok(x[i],y[i],tx,ty);
        }
        vis[a[0].id]=vis[b[0].id]=0;
        min1=sum;
        }
        if(a[1].id!=b[0].id){
        vis[a[1].id]=vis[b[0].id]=1;
        sum=a[1].val+b[0].val;
        for(int i=0;i<n;i++){
                sum+=2.0*ok(x[i],y[i],tx,ty);
        }
        vis[a[1].id]=vis[b[0].id]=0;
        min1=min(min1,sum);
        }
        if(a[0].id!=b[1].id){
        vis[a[0].id]=vis[b[1].id]=1;
        sum=a[0].val+b[1].val;
        for(int i=0;i<n;i++){
                sum+=2.0*ok(x[i],y[i],tx,ty);
        }
        vis[a[0].id]=vis[b[1].id]=0;
        min1=min(min1,sum);
        }
        sum=a[0].val;
        vis[a[0].id]=1;
        for(int i=0;i<n;i++){
            sum+=2.0*ok(x[i],y[i],tx,ty);
        }
        vis[a[0].id]=0;
        min1=min(min1,sum);
        sum=b[0].val;
        vis[b[0].id]=1;
        for(int i=0;i<n;i++){
            sum+=2.0*ok(x[i],y[i],tx,ty);
        }
        vis[b[0].id]=0;
        min1=min(min1,sum);
    printf("%.15f\n",(double)min1);
    return 0;
}




Codeforces Round #352 (Div. 2) D. Robin Hood


题目链接:点这里!!!


题意:

有n(n<=5e5)个人,每个人有ci(1<=ci<=1e9)枚金币。

有一个小偷喜欢劫富济贫,每一天从最富裕的人身上偷走一枚金币送给最贫穷人。(有多个最富裕或者最穷的人,随机偷,随机送) 

当所有人的金币都相同了,就不偷了。问k(k<=1e9)天后,最富裕的人的金币-最穷的人的金币为多少。


题解:

1、我们可以二分求出k天后最贫穷人的金币数为lb


2、我们可以二分求出k天后最富裕的人的金币数为rb


3、如果lb<rb直接输出rb-lb;如果lb>rb就要判断一下(因为已经没有到达k天贫富差距就没变了)。设总和为sum,如果sum%n==0 输出0;如果sum%n!=0输出1。


代码:


#include<cstdio>
#include<cstring>
#include<iostream>
#include<sstream>
#include<algorithm>
#include<vector>
#include<bitset>
#include<set>
#include<queue>
#include<stack>
#include<map>
#include<cstdlib>
#include<cmath>
#define PI 2*asin(1.0)
#define LL long long
#define pb push_back
#define pa pair<int,int>
#define clr(a,b) memset(a,b,sizeof(a))
#define lson lr<<1,l,mid
#define rson lr<<1|1,mid+1,r
#define bug(x) printf("%d++++++++++++++++++++%d\n",x,x)
#define key_value ch[ch[root][1]][0]C:\Program Files\Git\bin
const LL  MOD = 1000000007;
const LL N = 5e5+15;
const int maxn = 1e6+15;
const int letter = 130;
const LL INF = 1e18;
const double pi=acos(-1.0);
const double eps=1e-10;
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,k,a[N];
LL check1(int v){
    LL ans=0;
    for(int i=0;i<n;i++){
        if(a[i]<v) ans+=1ll*(v-a[i]);
    }
    return ans;
}
LL check2(int v){
    LL ans=0;
    for(int i=0;i<n;i++){
        if(a[i]>v) ans+=1ll*(a[i]-v);
    }
    return ans;
}
int main(){
    scanf("%d%d",&n,&k);
    LL sum=0;
    for(int i=0;i<n;i++)scanf("%d",a+i),sum+=1ll*a[i];
    int l=1,r=(int)(1e9),mid;
    int lf,rf;
    while(l+1<r){
        mid=(l+r)>>1;
        LL vs=check1(mid);
        if(vs<=k)l=mid;
        else r=mid;
    }
    lf=l;
    l=1,r=(int)1e9;
    while(l+1<r){
        mid=(l+r)>>1;
        LL vs=check2(mid);
        if(vs<=k)r=mid;
        else l=mid;
    }
    rf=r;
    if(rf-lf>0) printf("%d\n",rf-lf);
    else printf("%d\n",sum%n?1:0);
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值