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

 思路:分析完这道题后会发现  当两个人捡到第一个瓶子后, 之后走的路的最小值都是不会变的了。 所以只要找出两个走到各自的第一个瓶子是最小值的情况的时候(其中还有一个人不走,一个人走的情况)。   如果当有两个人或有一个人到其第一个瓶子的权值大于瓶子到回收点时,选取权值小的那个。

 

而且计算最小值的时候 只需取出两个权值数组中最小的两个数 即可 不用全部遍历来选取。

 

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

double a[100100],b[100100],t[100100];
double minn[4],sum,chang;
int under[4];

double distance(double x,double y,double x1,double y1){
    return sqrt(pow((x-x1)*1.0,2)+pow((y-y1)*1.0,2)+0.0);
}

int main(){
    //int ax,ay,bx,by,tx,ty,n,tempx,tempy;
    int n;
    double ax,ay,bx,by,tx,ty,tempx,tempy;
    scanf("%lf%lf%lf%lf%lf%lf",&ax,&ay,&bx,&by,&tx,&ty);
    scanf("%d",&n);
    
    sum=0;
    for(int i=1;i<=n;i++){
        scanf("%lf%lf",&tempx,&tempy);    
        t[i] = distance(tx,ty,tempx,tempy);
        sum += 2*t[i];
        a[i] = distance(ax,ay,tempx,tempy) - t[i];
        b[i] = distance(bx,by,tempx,tempy) - t[i];
        //cout<<a[i]<<" "<<b[i]<<endl;
    } 
    
    minn[0] = a[1];under[0] = 1;
    minn[2] = b[1];under[2] = 1;
    
    //找出a[i]数组的两个最小值 
    for(int i=1;i<=n;i++){
        if(a[i]<minn[0]){
            minn[0] = a[i];
            under[0] = i;
        }
    }
    
    for(int i=1;i<=n;i++) if(i!=under[0]) minn[1] = a[i],under[1] = i;
    
    for(int i=1;i<=n;i++){
        if(i!=under[0]&&a[i]<minn[1]){
            minn[1] = a[i];
            under[1] = i;
        }
    }
    
    //找出b[i]数组的两个最小值 
    for(int i=1;i<=n;i++){
        if(b[i]<minn[2]){
            minn[2] = b[i];
            under[2] = i;
        }
    }
    
    for(int i=1;i<=n;i++) if(i!=under[2]) minn[3] = b[i],under[3] = i;
    
    for(int i=1;i<=n;i++){
        if(i!=under[2]&&b[i]<minn[3]){
            minn[3] = b[i];
            under[3] = i;
        }
    }
    
    // 当n=1的时候会有就没有两个最小值了  所以要当成特殊情况?
    if(n==1) chang = min(a[1],b[1]);
    else if(under[0]!=under[2]){
        chang = min(min(minn[0]+minn[2],minn[0]),minn[2]);
    }else{
        chang = min(min(min(minn[0]+minn[3],minn[1]+minn[2]),minn[0]),minn[2]);
    }
    
    printf("%.12lf\n",sum+chang);
    
    return 0;
} 

 

转载于:https://www.cnblogs.com/yuanshixingdan/p/5491706.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值