二分法-二分查找的应用及三个经典例题
来源:互联网 发布:记考勤软件下载 编辑:程序博客网 时间:2024/06/15 11:33
二分法-二分查找应用及例题
在ICPC-ACM竞赛中,二分法是一种常用的解题策略,其中二分搜索是应用非常广泛的一种,主要使用的有STL中的binary_search()函数、lower_bound()函数、upper_bound()函数,这些函数一般要配合sort()、unique()函数使用。
1. binary_search(begin,end,index):在数组中,若找到index则返回1,找不到就返回0
2.lower_bound(begin,end,index):在数组中的[begin,end)前闭后开区间内,返回大于或等于index的第一个元素位置,如果都小于index,则返回end。
3.upper_bound(begin,end,index):在数组中的[begin,end)前闭后开区间内,返回大于index的第一个元素位置,如果都小于index,则返回end。
4.sort()和unique(),sort()用于对数组排序,一般在二分查找之前使用,unique(),用于对数组去重,某些情况下可用到。
例题
POJ - 2785 4 Values whose Sum is 0
The SUM problem can be formulated as follows: given four lists A, B, C, D of integer values, compute how many quadruplet (a, b, c, d ) ∈ A x B x C x D are such that a + b + c + d = 0 . In the following, we assume that all lists have the same size n .
Input
The first line of the input file contains the size of the lists n (this value can be as large as 4000). We then have n lines containing four integer values (with absolute value as large as 2 28 ) that belong respectively to A, B, C and D .
Output
For each input file, your program has to write the number quadruplets whose sum is zero.
Sample Input
6
-45 22 42 -16
-41 -27 56 30
-36 53 -37 77
-36 30 -75 -46
26 -38 -10 62
-32 -54 -6 45
Sample Output
5
Hint
Sample Explanation: Indeed, the sum of the five following quadruplets is zero: (-45, -27, 42, 30), (26, 30, -10, -46), (-32, 22, 56, -46),(-32, 30, -75, 77), (-32, -54, 56, 30).
此题思路是将四个数组分成两份,第一个数组求所有数对的和,得到数组a,第二个数组求所有数对的和的相反数,得到数组b,然后在a中查找b中的元素(若找到则相加等于0),然后使用upper_bound(sum1,sum1+m,k)-lower_bound(sum1,sum1+m,k)
即得到重复和数对的个数解,所有解相加即得答案。
答案:
//二分法+stl#include<cstdio>#include<iostream>#include<algorithm>using namespace std;const int maxn=4020;int a[maxn],b[maxn],c[maxn],d[maxn],sum1[maxn*maxn];int main(){ int n; while(~scanf("%d",&n)){ int m=0; for(int i=0;i<n;i++) cin>>a[i]>>b[i]>>c[i]>>d[i]; for(int j=0;j<n;j++) for(int i=0;i<n;i++) sum1[m++]=a[j]+b[i]; sort(sum1,sum1+m); long long ans=0; for(int i=0;i<n;i++) for(int j=0;j<n;j++) { int k=-(c[i]+d[j]); ans+=upper_bound(sum1,sum1+m,k)-lower_bound(sum1,sum1+m,k); }cout<<ans<<endl;}}
HDU - 2141 Can you find it?
Give you three sequences of numbers A, B, C, then we give you a number X. Now you need to calculate if you can find the three numbers Ai, Bj, Ck, which satisfy the formula Ai+Bj+Ck = X.
Input
There are many cases. Every data case is described as followed: In the first line there are three integers L, N, M, in the second line there are L integers represent the sequence A, in the third line there are N integers represent the sequences B, in the forth line there are M integers represent the sequence C. In the fifth line there is an integer S represents there are S integers X to be calculated. 1<=L, N, M<=500, 1<=S<=1000. all the integers are 32-integers.
Output
For each case, firstly you have to print the case number as the form “Case d:”, then for the S queries, you calculate if the formula can be satisfied or not. If satisfied, you print “YES”, otherwise print “NO”.
Sample Input
3 3 3
1 2 3
1 2 3
1 2 3
3
1
4
10
Sample Output
Case 1:
NO
YES
NO
Hint
Sample Explanation: Indeed, the sum of the five following quadruplets is zero: (-45, -27, 42, 30), (26, 30, -10, -46), (-32, 22, 56, -46),(-32, 30, -75, 77), (-32, -54, 56, 30).
此题笔者疯狂MLE了十多次,此题要求的Memory limit 为10000 kB ,Time limit为3000 ms 显然不能用三个for,同样分为2个组
#include<bits/stdc++.h>#define maxn 505using namespace std;int L[maxn],M[maxn],N[maxn],sum[maxn*maxn];int main(){ //int num=0; int l,m,n,s,s2; int kase=1; while(scanf("%d%d%d",&l,&m,&n)!=EOF) { for(int i=0;i<l;i++) scanf("%d",&L[i] ); for(int j=0;j<m;j++) scanf("%d",&M[j] ); for(int k=0;k<n;k++) scanf("%d",&N[k]); int num=0; for(int i=0;i<l;i++) for(int j=0;j<m;j++) sum[num++]=L[i]+M[j]; sort(sum,sum+num); scanf("%d",&s ); printf("Case %d:\n",kase++);while(s--) {scanf("%d",&s2 );int flag=0;for(int i=0;i<n;i++){ if(binary_search(sum,sum+num,s2-N[i])) {flag=1; break; }}if(flag) puts("YES");else puts("NO"); } }}
POJ - 3579 Median
Given N numbers, X1, X2, … , XN, let us calculate the difference of every pair of numbers: ∣Xi - Xj∣ (1 ≤ i < j ≤ N). We can get C(N,2) differences through this work, and now your task is to find the median of the differences as quickly as you can!
Note in this problem, the median is defined as the (m/2)-th smallest number if m,the amount of the differences, is even. For example, you have to find the third smallest one in the case of m = 6.
Input
The input consists of several test cases.
In each test case, N will be given in the first line. Then N numbers are given, representing X1, X2, … , XN, ( Xi ≤ 1,000,000,000 3 ≤ N ≤ 1,00,000 )
Output
For each test case, output the median in a separate line.
Sample Input
4
1 3 2 4
3
1 10 2
Sample Output
1
8
这题是利用二分法枚举答案,用二分查找判断是否是中位数,个人感觉比较难理解判断代码
#include<iostream>#include<cstdio>#include<algorithm>using namespace std;const int N = 100005;int a[N], n, m;bool judge(int x) { int cnt = 0; for (int i = 0; i < n; i++) cnt += n - (lower_bound(a, a + n, a[i] + x) - a); return cnt > m ? true : false;//如果这个数恰好是}int main() { while (~scanf("%d", &n)) { m = n * (n - 1) / 4; for (int i = 0; i < n; i++) scanf("%d", &a[i]); sort(a, a + n); int l = 0, r = a[n - 1]; while (l <= r) { int mid = (l + r) / 2; if (judge(mid)) l = mid + 1; else r = mid - 1; } printf("%d\n", l - 1); } return 0;}
- 二分法-二分查找的应用及三个经典例题
- 二分查找(二分法的应用)
- 经典例题——二分查找
- 经典的二分查找
- 二分查找例题
- 二分查找及简单应用
- 二分查找的应用
- 二分查找的应用
- 【算法总结-二分法】 二分查找法的相关总结
- 二分法实现一个整形有序数组的二分查找
- 《顺序表和单链表的区别及应用场景+单链表经典例题》
- 二分法查找,插入法查找及冒泡排序的改进
- 二分查找的简单应用
- 二分查找的变形应用
- 二分查找的灵活应用
- 双重二分查找的应用
- 一个经典的二分查找算法
- 一个经典的二分查找算法
- 方法参数的传递过程
- php常用日期函数
- (官方)(新)cocos2d-x 接Firebase &Admob
- 【概率论】作业七
- 深入理解Spring4框架(一)——简介
- 二分法-二分查找的应用及三个经典例题
- windows下map类中二级指针的用法
- html 查看物流信息详情
- 和为k的连续区间 51Nod
- java中IO流
- 基于顺序表实现线性表
- 线性表的顺序表示及实现
- 11.1发布
- swift学习笔记3-数组、字典