Codeforces Round #352 (Div. 2) C D

来源:互联网 发布:淘宝效果评估 编辑:程序博客网 时间:2024/06/06 07:30

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\binconst 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\binconst 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;}



0 0
原创粉丝点击