赞
踩
1. 确定一个区间,使得目标值在一定区间中
2. 找一个性质满足:性质具有二段性;答案是二段性的分界点
整数二分:
第一类:ans是红色区间的右端点(ans>=x)
将[L,R]分为[L,M-1]和[M,R]
ps:区间不是[L,M]的原因:M正好为红色时无法区分是在[L,M]还是[M+1,R]
if M是红色的,说明ans在区间[M,R]
else 说明ans在区间[L,M-1]
伪代码如下:注意算M时要+1,防止向下取整时发生死循环
while l<r: m = l + r + 1 >> 1 # 等同(l+r+1)//2 if m红: l = m # l=m时,需要+1 else: r = m - 1
第二类:ans是绿色区间的左端点(ans<=x)
将[L,R]分为[L,M]和[M+1,R]
if M是绿色的,说明ans在区间[L,M]
else 说明ans在区间[M+1,R]
伪代码如下:
while l<r: m = l + r >> 1 # 等同(l+r)//2 if m绿: r = m # l=m时,不需要+1 else: l = m + 1
思路:
1. 更据题目最后要求的量划分二分区域找到隔板
2. 套模板,思考isBlue函数应该怎么写,也就是什么是时候选择区间的左半部分。l和r的初始值需要比整个区间小1和大1。
3. 最后的值是l还是r
代码模板,每次根据题意改变isBlue函数:
def isBlue(n): if n<target: return True else: return False nums = [5,7,7,8,8,10] target = 8 l=-1 r=len(nums) while l+1!=r: mid=l+r>>1 if isBlue(nums[mid]): l=mid else: r=mid print(l,r)
- n,q=map(int,input().split())
- s=list(map(int,input().split()))
- for i in range(q):
- find=int(input())
- #左边界
- l=0
- r=n-1
- while l<r:
- mid= l+r>>1 #等同(l+r)//2
- if s[mid]>=find:
- r=mid #r=mid时,不需要要+1
- else:
- l=mid+1
- if s[l]==find: #注意是l不是mid
- print(l,end=" ")
- else:
- print(-1,end=" ")
- #右边界
- l = 0
- r = n - 1
- while l < r:
- mid = l + r + 1 >> 1
- if s[mid] <= find:
- l = mid
- else:
- r = mid - 1
- if s[l] == find:
- print(l)
- else:
- print(-1)
-
要点:
1.每块巧克力分的时候不可以拼接
2.每个人分得的巧克力大小相同
3.二分方法:以需要分的数量k作为临界点,当分的大小<=最大值时,sum(分得的巧克力数量)>=k
- n,k=map(int,input().split())
- h=[]
- w=[]
- for i in range(n):
- a,b=map(int,input().split())
- h.append(a)
- w.append(b)
- def check(m):
- sum=0
- for i in range(n):
- sum+=(h[i]//m)*(w[i]//m)#计算分的巧克力的总量
- if sum>=k:
- return True
- else:
- return False
- #以需要分的数量k作为临界点,当分的大小<=最大值时,sum(分得的巧克力数量)>=k
- l=1
- r=100000
- while l<r:
- m=l+r+1>>1
- if check(m):
- l=m
- else:
- r=m-1
- print(l)
利用数列的前n项和来求下标从L,R和的值
思路:
1. 如何计算前缀和矩阵
2. 如何计算询问的结果
- n, m, q = map(int, input().split())
- grid=[[0 for i in range(m+1)]for j in range(n+1)]
- sum_grid=[[0 for i in range(m+1)]for j in range(n+1)] #前缀和矩阵
- #输入
- for i in range(n):
- a=list(map(int,input().split()))
- for j in range(m):
- grid[i+1][j+1]=a[j]
- #计算前缀和
- for i in range(1,n+1):
- for j in range(1,m+1):
- sum_grid[i][j]=sum_grid[i][j-1]+sum_grid[i-1][j]+grid[i][j]-sum_grid[i-1][j-1]
- result=[]
- #输出查询结果
- for i in range(q):
- x1,y1,x2,y2=map(int, input().split())
- sum=sum_grid[x2][y2]-sum_grid[x2][y1-1]-sum_grid[x1-1][y2]+sum_grid[x1-1][y1-1]
- result.append(sum)
- for i in result:
- print(i)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。