> 文档中心 > 二分法(分巧克力、跳石头、一元三次方程求解)

二分法(分巧克力、跳石头、一元三次方程求解)


1.分巧克力 

题目描述

儿童节那天有 K 位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。

小明一共有 N 块巧克力,其中第 i 块是 Hi​×Wi 的方格组成的长方形。为了公平起见,

小明需要从这 N 块巧克力中切出 K 块巧克力分给小朋友们。切出的巧克力需要满足:

  1. 形状是正方形,边长是整数;

  2. 大小相同;

例如一块 6×5​ 的巧克力可以切出 6 块2×2​ 的巧克力或者 2 块 3×3 的巧克力。

当然小朋友们都希望得到的巧克力尽可能大,你能帮小明计算出最大的边长是多少么?

输入描述

第一行包含两个整数 N,K (1≤N,K≤10^5)。

以下 N 行每行包含两个整数 Hi​,Wi​ (1≤Hi​,Wi​≤10^5)。

输入保证每位小朋友至少能获得一块 1×1 的巧克力。

输出描述

输出切出的正方形巧克力最大可能的边长。

样例输入

2 106 55 6样例输出2 

1.二分法:如果这个数check为True,就往后取,如果为False,就往前去

一直到左右相等

2.不同于找数,这个是找最大数

n, k = map(int, input().split())def check(d):    global w, h    res = 0    for i in range(len(w)): res += (w[i]//d) * (h[i]//d)    if res >= k: return Truew = []h = []for i in range(n):    a, b = map(int, input().split())    w.append(a)    h.append(b)L, R = 1, 100000while L < R:    mid = (L+R)//2    if check(mid): L = mid+1    else: R = midif check(L):#最后一步是R=mid,但是左边的left没check    print(L)else:    print(L-1)

 

2.跳石头 

题目描述

一年一度的「跳石头」比赛又要开始了!

这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间,有 N 块岩石(不含起点和终点的岩石)。在比赛过程中,选手们将从起点出发,每一步跳向相邻的岩石,直至到达终点。

为了提高比赛难度,组委会计划移走一些岩石,使得选手们在比赛过程中的最短跳跃距离尽可能长。由于预算限制,组委会至多从起点和终点之间移走M块岩石(不能移走起点和终点的岩石)。

输入描述

输入文件第一行包含三个整数 L,N,M分别表示起点到终点的距离,起点和终点之间的岩石数,以及组委会至多移走的岩石数。

接下来 N行,每行一个整数,第 ii行的整数 Di​(0<Di​<L)表示第 ii 块岩石与起点的距离。这些岩石按与起点距离从小到大的顺序给出,且不会有两个岩石出现在同一个位置。

其中,0≤MN≤5×10^4,1≤L≤10^9。

输出描述

输出只包含一个整数,即最短跳跃距离的最大值。

样例输入

25 5 2211141721

样例输出

4

 1.在 n块岩石中选 m块石头,有 m!/(n−m)!n!​ 种组合,实在是太多了。转换思路,现在我们不去找搬走石头的各种组合,而是给出一个距离 d,检查能不能搬走 m 块石头而得到最短距离 d

(判断它与前一块石头的距离是不是小于最短距离,如果小于最短距离,这块石头就得移走。)

2.如果总共搬的石头小于给的数目,说明距离d可以达到。

3.用二分查找,同巧克力,找到符合条件的最大数。

l,n,m=map(int,input().split())p=[]for i in range(n):    p.append(int(input()))def check(d):    pos=0    num=0    for i in range(n): #两个石块之间的距离大于d(最小的距离可能是d),要搬走的石块数 if (p[i]-pos)<d:     num+=1 else:     pos=p[i]    if num<=m: return True    else: return FalseL,R=1,lwhile L<R:    mid=(L+R)//2    if check(mid): L=mid+1    else: R=midif check(L):   print(L)else:   print(L-1)

 

n = input().split()a,b,c,d = eval(n[0]),eval(n[1]),eval(n[2]),eval(n[3])def y(x): return a*x*x*x+b*x*x+c*x+dfor i in range(-100,100):    left=i    right=i+1    y1=y(left)    y2=y(right)    if y1==0: print("{:.2f}".format(left),end=" ")    if y1*y2= 0.001:    #eps=0.001     mid = (left+right)/2     if y(mid)*y(right) <=0:  left = mid     else:  right = mid print("{:.2f}".format(right),end=" ")