【模拟】Codeforces 671A Recycling Bottles

本文详细解析了CodeForces 671A题目的解题思路,采用模拟策略,通过计算从垃圾桶往返捡垃圾的最短路径,并优化其中一个垃圾的直接捡取方式,以减少总行走距离。

题目链接:

  http://codeforces.com/problemset/problem/671/A

题目大意:

  A和B在一张二维平面上,平面上有N个垃圾,垃圾桶只有一个在T,问把所有垃圾全扔进垃圾桶最少走多远。一次只能拿一个垃圾。允许一个人走另一个人停下来。

  (1 ≤ n ≤ 100 000)  (0 ≤ xi, yi ≤ 109

题目思路:

  【模拟】

  因为每次只能携带一个垃圾,大部分垃圾都是人扔完上一个垃圾后,从垃圾桶出发去捡的。

  而最多有两个垃圾不是被人从垃圾桶出发完再扔到垃圾桶。

  可以先将答案算作都从垃圾桶开始往返捡的距离,再枚举哪一个垃圾被人直接走过去捡能优化答案。注意不要让两个人都选择同一个垃圾。

 

  1 //
  2 //by coolxxx
  3 //#include<bits/stdc++.h>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<string>
  7 #include<iomanip>
  8 #include<map>
  9 #include<memory.h>
 10 #include<time.h>
 11 #include<stdio.h>
 12 #include<stdlib.h>
 13 #include<string.h>
 14 //#include<stdbool.h>
 15 #include<math.h>
 16 #define min(a,b) ((a)<(b)?(a):(b))
 17 #define max(a,b) ((a)>(b)?(a):(b))
 18 #define abs(a) ((a)>0?(a):(-(a)))
 19 #define lowbit(a) (a&(-a))
 20 #define sqr(a) ((a)*(a))
 21 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))
 22 #define mem(a,b) memset(a,b,sizeof(a))
 23 #define eps (1e-8)
 24 #define J 10
 25 #define mod 1000000007
 26 #define MAX 0x7f7f7f7f
 27 #define PI 3.14159265358979323
 28 #define N 100004
 29 using namespace std;
 30 typedef long long LL;
 31 int cas,cass;
 32 int n,m,lll,ans;
 33 double anss;
 34 struct xxx
 35 {
 36     LL x,y;
 37     double disa,disb,dist;
 38 }q[N],a,b,t;
 39 double dis(xxx aa,xxx bb)
 40 {
 41     return sqrt(sqr(aa.x-bb.x)+sqr(aa.y-bb.y));
 42 }
 43 bool cmp(xxx aa,xxx bb)
 44 {
 45     return aa.dist<bb.dist;
 46 }
 47 int main()
 48 {
 49     #ifndef ONLINE_JUDGE
 50     freopen("1.txt","r",stdin);
 51 //    freopen("2.txt","w",stdout);
 52     #endif
 53     int i,j,ma,mb;
 54     double ax,ay,bx,by,z;
 55 //    for(scanf("%d",&cas);cas;cas--)
 56 //    for(scanf("%d",&cas),cass=1;cass<=cas;cass++)
 57     while(~scanf("%I64d",&a.x))
 58 //    while(~scanf("%d",&n))
 59     {
 60         anss=0;ay=by=0;
 61         scanf("%I64d%I64d%I64d%I64d%I64d",&a.y,&b.x,&b.y,&t.x,&t.y);
 62         scanf("%d",&n);
 63         for(i=1;i<=n;i++)
 64         {
 65             scanf("%I64d%I64d",&q[i].x,&q[i].y);
 66             q[i].disa=dis(a,q[i]);
 67             q[i].disb=dis(b,q[i]);
 68             q[i].dist=dis(t,q[i]);
 69         }
 70         sort(q+1,q+1+n,cmp);
 71         anss=q[1].dist+q[1].dist;
 72         ax=q[1].dist-q[1].disa;
 73         bx=q[1].dist-q[1].disb;
 74         ma=mb=1;
 75         for(i=2;i<=n;i++)
 76         {
 77             anss+=q[i].dist+q[i].dist;
 78             z=q[i].dist-q[i].disa;
 79             if(ax<z)
 80             {
 81                 ay=max(ax,ay);
 82                 ax=z;
 83                 ma=i;
 84             }
 85             else ay=max(ay,z);
 86             z=q[i].dist-q[i].disb;
 87             if(bx<z)
 88             {
 89                 by=max(bx,by);
 90                 bx=z;
 91                 mb=i;
 92             }
 93             else by=max(by,z);
 94         }
 95         if(ma!=mb)z=ax+bx;
 96         else z=max(ax+by,bx+ay);
 97         z=max(z,ax);
 98         z=max(z,bx);
 99         printf("%.12lf\n",anss-z);
100     }
101     return 0;
102 }
103 /*
104 //
105 
106 //
107 */
View Code

 

转载于:https://www.cnblogs.com/Coolxxx/p/5785014.html

先展示下效果 https://pan.quark.cn/s/a4b39357ea24 遗传算法 - 简书 遗传算法的理论是根据达尔文进化论而设计出来的算法: 人类是朝着好的方向(最优解)进化,进化过程中,会自动选择优良基因,淘汰劣等基因。 遗传算法(英语:genetic algorithm (GA) )是计算数学中用于解决最佳化的搜索算法,是进化算法的一种。 进化算法最初是借鉴了进化生物学中的一些现象而发展起来的,这些现象包括遗传、突变、自然选择、杂交等。 搜索算法的共同特征为: 首先组成一组候选解 依据某些适应性条件测算这些候选解的适应度 根据适应度保留某些候选解,放弃其他候选解 对保留的候选解进行某些操作,生成新的候选解 遗传算法流程 遗传算法的一般步骤 my_fitness函数 评估每条染色体所对应个体的适应度 升序排列适应度评估值,选出 前 parent_number 个 个体作为 待选 parent 种群(适应度函数的值越小越好) 从 待选 parent 种群 中随机选择 2 个个体作为父方和母方。 抽取父母双方的染色体,进行交叉,产生 2 个子代。 (交叉概率) 对子代(parent + 生成的 child)的染色体进行变异。 (变异概率) 重复3,4,5步骤,直到新种群(parentnumber + childnumber)的产生。 循环以上步骤直至找到满意的解。 名词解释 交叉概率:两个个体进行交配的概率。 例如,交配概率为0.8,则80%的“夫妻”会生育后代。 变异概率:所有的基因中发生变异的占总体的比例。 GA函数 适应度函数 适应度函数由解决的问题决定。 举一个平方和的例子。 简单的平方和问题 求函数的最小值,其中每个变量的取值区间都是 [-1, ...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值