二分与三分

  (写的很早忘了发布了...)今天高二的学长学姐们进行了二分和三分的测试(又名一本通课后题测试),感觉这个好有意思~

  关于什么是二分,三分,先咕咕咕了,来看一道题。

  灯泡:https://loj.ac/problem/10016

  

  题意概述:给出$H,h,D$,求阴影的最长长度(包括地上的和墙上的)。

  有种初中数学的既视感。

  解:设灯泡为$A$,人头为$B$,连接$AB$并延长,与地面的延长线交于点$C$.

  

  

  

  于是就结束了...吗?

  还有一种可能就是影子并没有到墙上去,但是影响不大,两个函数叠加起来还是单峰的,似乎就是那种对勾函数? 

  

 1 # include <cstdio>
 2 # include <iostream>
 3
 4 using namespace std;
 5
 6 int T;
 7 double H,h,d,a1,a2;
 8 double ans,l,r,lmid,rmid;
 9
10 double f (double x)
11 {
12     double ans=0,a,b;
13     b=h*(d-x)/(H-h);
14     if(b<=x)
15         return b;
16     ans+=x;
17     a=(x*H-d*h)/(h-H);
18     ans+=a*h/(x+a);
19     return ans;
20 }
21
22 int main()
23 {
24     scanf("%d",&T);
25     while (T--)
26     {
27         scanf("%lf%lf%lf",&H,&h,&d);
28         l=0,r=d,ans=0;
29         while (r-l>=0.0001)
30         {
31             lmid=l+(r-l)/3.0;
32             rmid=r-(r-l)/3.0;
33             a1=f(lmid);
34             a2=f(rmid);
35             if(f(lmid)<f(rmid))
36                 l=lmid;
37             else
38                 r=rmid;
39         }
40         printf("%.3lf\n",f(l));
41     }
42     return 0;
43 }

灯泡

  迎风舞:https://www.cnblogs.com/shzr/p/9751719.html

  传送带:https://www.luogu.org/problemnew/show/P2571

  题意概述:给定平面上的两条线段,在每条上移动的速度分别是$a$,$b$,也可以脱离线段到平面上走,同样有一个速度$c$,求从第一条线段上的$A$点到另一条上的$D$点的最短距离.

  首先想到的是贪心...如果平面上走的快就到面上去,如果线上更快就在线上走,然而这个显然是错的,因为有时虽然线上走的快,但是却越走越偏?

  最终的答案应该是在起始线段上走一段,再在平面上走一段到达终点线段,再在那条线段上一直走到终点.先考虑一个比较简单的问题,如果只是平面上有一条线段,求从某个点到线段端点的最小距离怎么做?列方程发现是一个二次函数,可以求出系数来求极值,也可以三分.现在考虑起始点不固定的情况:如果对于每个起始点都求出最小距离,可以视为一个关于起始点的函数.首先这个函数应该是连续的,所以要是想不明白上模拟退火也行,显然它不一定是单调的,但是应该也不是特别奇怪的形状,严谨的证明其实我也不会,但是可以感受一下.最优解肯定是存在的,而且起始点越偏离最优解答案就越劣.为什么?以下是胡乱证明,不保证正确:起始点移动一点,到达点也会相应的移动一些,在很小的范围内这种移动可能是单调的,但是过了某一个点之后就会往反方向移动?

  

  总之网上也没找到好的证明,就这样吧.

  注意:有可能某一条线段退化成一个点,三分还没开始就退出了...可以考虑换成控制三分次数的做法.

  

 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cmath>
 4 # include <algorithm>
 5
 6 using namespace std;
 7
 8 const int maxn=300;
 9 int ax,ay,bx,by;
10 int cx,cy,dx,dy;
11 double p,q,r;
12 double la,lb,L,R,lmid,rmid;
13 int cnt=maxn;
14
15 inline double l (double len,double x,double y)
16 {
17     double ans=0,x_,y_;
18     x_=cx,y_=cy;
19     if(lb) x_=len*(dx-cx)/lb+cx;
20     if(lb) y_=len*(dy-cy)/lb+cy;
21     ans+=sqrt((x_-dx)*(x_-dx)+(y_-dy)*(y_-dy))/q;
22     ans+=sqrt((x-x_)*(x-x_)+(y-y_)*(y-y_))/r;
23     return ans;
24 }
25
26 inline double f (double len)
27 {
28     double L=0,R=lb,lmid,rmid,x,y,l1;
29     x=ax,y=ay;
30     if(la) x=len*(bx-ax)/la+ax;
31     if(la) y=len*(by-ay)/la+ay;
32     l1=sqrt((x-ax)*(x-ax)+(y-ay)*(y-ay))/p;
33     int cnt=maxn;
34     while (cnt)
35     {
36         lmid=L+(R-L)/3.0;
37         rmid=R-(R-L)/3.0;
38         if(l(lmid,x,y)>l(rmid,x,y))
39             L=lmid;
40         else R=rmid;
41         cnt--;
42     }
43     return l(L,x,y)+l1;
44 }
45
46 int main()
47 {
48     scanf("%d%d%d%d",&ax,&ay,&bx,&by);
49     scanf("%d%d%d%d",&cx,&cy,&dx,&dy);
50     scanf("%lf%lf%lf",&p,&q,&r);
51     la=sqrt((ax-bx)*(ax-bx)+(ay-by)*(ay-by));
52     lb=sqrt((cx-dx)*(cx-dx)+(cy-dy)*(cy-dy));
53     L=0,R=la;
54     while (cnt)
55     {
56         lmid=L+(R-L)/3.0;
57         rmid=R-(R-L)/3.0;
58         if(f(lmid)>f(rmid))
59             L=lmid;
60         else R=rmid;
61         cnt--;
62     }
63     printf("%.2lf",f(R));
64     return 0;
65 }

传送带

---shzr

原文地址:https://www.cnblogs.com/shzr/p/9630662.html

时间: 2024-10-04 02:21:53

二分与三分的相关文章

ACM之路(1)——对二分及三分的研究

对于二分来说,个人暂且将其分为整数型和实数型.      对整数型而言,一般问题对于(low<=high)条件的判断取等号即可,因为在while途中查找遇到可匹配的便break,比方说二分查找已排序的数列.但是有些问题并不是这样的,在此分为两类:取最大值的min,和取最小值的max.      对于前一种,要用<(即不断往下推得最优解),而后一种要用<=(即不断往上推得最优解).同时,若对于前一种情况而言,因为要取最小的最优解,那么即使取中的mid可以满足条件仍要将high=mid-1以

二分与三分(精度类型)

二分:传送门 三分:传送门 (注意,是五舍六入,不是四舍五入,在2018年10月23日前是这样的) 话说一本通上不是有讲嘛,做法自己看吧...(但是我太弱了,精度版看不懂QWQ). 简单讲一下二分与三分吧. 二分:必须满足单调性: 非增或非减就叫单调性(如果就好几个数相同,一般会用二分来找第一个数或最后一个数). 我们用两个数字l与r来代表搜索范围,而mid代表中间的位置的值,来跳来跳去,看情况来写. 如这题 int l=1,r=n,mid,ans=0; while(l<=r) { mid=(l

【信息学奥赛一本通】Part1.2 基础算法-二分与三分

问题 A: [二分和三分]愤怒的牛 题目描述 农夫约翰建造了一座有n间牛舍的小屋,牛舍排在一条直线上,第i间牛舍在xi的位置,但是约翰的m头牛对小屋很不满意,因此经常互相攻击.约翰为了防止牛之间互相伤害,因此决定把每头牛都放在离其它牛尽可能远的牛舍.也就是要最大化最近的两头牛之间的距离. 牛们并不喜欢这种布局,而且几头牛放在一个隔间里,它们就要发生争斗.为了不让牛互相伤害.John决定自己给牛分配隔间,使任意两头牛之间的最小距离尽可能的大,那么,这个最大的最小距离是多少呢? 输入 第一行用空格分

ACM : HDU 2899 Strange fuction 解题报告 -二分、三分

Strange fuction Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5933 Accepted Submission(s): 4194 Problem Description Now, here is a fuction: F(x) = 6 * x^7+8*x^6+7*x^3+5*x^2-y*x (0 <= x <=100) C

hdu 2899 凸性 二分 / 三分

Strange fuction Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7230    Accepted Submission(s): 4996 Problem Description Now, here is a fuction:  F(x) = 6 * x^7+8*x^6+7*x^3+5*x^2-y*x (0 <= x <=

二分和三分

二分: 二分,即为折半查找,它是一种效率较高的查找方法.但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列. 也就是说,二分的条件为必须满足数列或某一逻辑的顺序性,(单调 只有这样才能进行二分. 查找方法: 首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表.重复以上过程,直到找到满足条件的记录,

《算法竞赛进阶指南》学习总结 二分与三分

首先......我是一个很菜很菜的萌新,所以这篇文章写得很详细,有很多我自己的口水话方便我理解,请各位谨慎食用qwq 以前在网上找过很多介绍二分的博客,但都感觉对萌新不太友好,反正我当时连跳石头都没看懂,所以决定自己写一篇!其中有我的想法,也借鉴了书里的很多内容,感谢lyd. 二分答案,顾名思义,就是对我们所需要的答案进行二分,对我们要求的值进行二分.二分的基础用法是在单调序列或者单调函数当中查找,当答案具有单调性,我们就可以采用二分来计算,当然还有三分,在后面我会详细讲到 整数集合上的二分 在

【信息学奥赛一本通 提高组】第二章 二分与三分

一.二分 二分法,在一个单调有序的集合或函数中查找一个解,每次分为左右两部分,判断解在那个部分并调整上下界,直到找到目标元素,每次二分都将舍弃一般的查找空间,因此效率很高. 二分常见模型 1.二分答案 最小值最大(或是最大值最小)问题,这类双最值问题常常选用二分法求解,也就是确定答案后,配合贪心,DP等其他算法检验这个答案是否合理,将最优化问题转化为判定性问题.例如,将长度为n的序列ai分为最多m个连续段,求所有分法中每段和的最大值的最小是多少? 2.二分查找 用具有单调性的布尔表达式求解分界点

2019年8月训练(壹)二分,三分

二分查找 P1024 一元三次方程求解 题目给出范围[-100,100],同时两根绝对值之差<=1,保证了每一个大小为1的区间里至多有1个解,也就是说当区间的两个端点的函数值异号时区间内一定有一个解,同号时一定没有解. 也就可以二分去做查找. AC码: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; double a,b,c,d; double f(double