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;
} 
时间: 2024-07-29 15:57:11

Codeforces Round #352 (Div. 2) C. Recycling Bottles(枚举)的相关文章

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

C. Recycling Bottles It was recycling day in Kekoland. To celebrate it Adil and Bera went to Central Perk where they can take bottles from the ground and put them into a recycling bin. We can think Central Perk as coordinate plane. There are n bottle

[Codeforces] Round #352 (Div. 2)

人生不止眼前的狗血,还有远方的狗带 A题B题一如既往的丝帛题 A题题意:询问按照12345678910111213...的顺序排列下去第n(n<=10^3)个数是多少 题解:打表,输出 1 #include<bits/stdc++.h> 2 using namespace std; 3 int dig[10],A[1005]; 4 int main(){ 5 int aa=0; 6 for(int i=1;;i++){ 7 int x=i,dd=0; 8 while(x)dig[++dd

Codeforces Round #352 (Div. 2) ABCD

Problems # Name     A Summer Camp standard input/output 1 s, 256 MB    x3197 B Different is Good standard input/output 2 s, 256 MB    x2870 C Recycling Bottles standard input/output 2 s, 256 MB    x664 D Robin Hood standard input/output 1 s, 256 MB  

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

题目连接请戳此处 题意:n个人每人有一定的财富值ci,每天Robin Hood从最富的人手中取财富1分给最穷的人(取后最穷, 即可以退回),若有多个最穷的人,任选一个给出财富值.问k天后最富的人和最穷的人财富差值为多少. 1 ≤ n ≤ 500 000, 0 ≤ k ≤ 109 1 ≤ ci ≤ 109 分析: 每一天随着财富值的取和给,最穷的人和最富的人都在动态更新. 最后要求的是  (richest-poorest)min,那么  要使这个等式最小,只需求出k天后richest的最小值和po

Codeforces Round #352 (Div. 2) D. Robin Hood (二分法+判断平衡态)

解题思路: 由求最小值和求最大值各自二分. 由l*(a[l+1]-a[l]):求取填 1~l 到a[l+1]的高度需要多少的钱,如果大于剩余的k 则可执行 若否 判断剩余的k是否为l,若否最小值为a[l],否则 为a[l]+k/l; 由(n-r+1)*(a[r]-a[r-1]):求去掉n~n-r+1的这部分需要多少钱,如果大于剩余的k 则执行 若否 判断剩余的k是否为n-r+1,若是最大值为a[n-r+1]-k/(n-r+1); 如果最大值小于最大值,直接printf 如果最小值大于等于最大值,

Codeforces Round #352 (Div. 2) B - Different is Good

A wise man told Kerem "Different is good" once, so Kerem wants all things in his life to be different. Kerem recently got a string s consisting of lowercase English letters. Since Kerem likes it when things are different, he wants allsubstrings 

Codeforces Round #352 (Div. 2) A Summer Camp

Every year, hundreds of people come to summer camps, they learn new algorithms and solve hard problems. This is your first year at summer camp, and you are asked to solve the following problem. All integers starting with 1 are written in one line. Th

Codeforces Round #266 (Div. 2)B(暴力枚举)

很简单的暴力枚举,却卡了我那么长时间,可见我的基本功不够扎实. 两个数相乘等于一个数6*n,那么我枚举其中一个乘数就行了,而且枚举到sqrt(6*n)就行了,这个是暴力法解题中很常用的性质. 这道题找出a和b中最小的那个,然后开始枚举,一直枚举到sqrt(6*n)的向上取整.这样所有可能是答案的情况都有啦.再干别的都是重复的或者肯定不是最小面积的. #include<iostream> #include<cstdio> #include<cstdlib> #includ

Codeforces Round #266 (Div.2) B Wonder Room --枚举

题意:给出一个两边长为a,b的矩形,要求增加a和增加b使a*b>=6*n且a*b最小. 解法:设新的a,b为a1,b1,且设a<b,那么a<=a1<=ceil(sqrt(6*n)),那么我们可以枚举a1,然后算出b1,如果b1<b,那么b1 = b,然后算出面积,取所有面积的最小值不就可以了,然后再枚举一次b1,处理与之相同即可. 复杂度O(sqrt(n)) 代码: #include <iostream> #include <cstdio> #incl