二分查找
来源:互联网 发布:羞辱2优化补丁 编辑:程序博客网 时间:2024/05/17 11:56
二分查找:
例题一:
题目来源:HDOJ-2199:Can you solve this equation?
题目大意:给出一个方程8*x^4 + 7*x^3 + 2*x^2 + 3*x + 6 == Y,再给出一个Y,求出0~100之间的解。
题目分析:最基础的二分查找问题。
AC代码:
#include <stdio.h>#include <math.h>double f(double x){ return 8*pow(x,4)+7*pow(x,3)+2*pow(x,2)+3*x+6;}double abs(double a)//求绝对值{ return a>0?a:-a;}int main(){ int t; double y,left,right,mid; scanf("%d",&t); while(t--) { scanf("%lf",&y); if(y<f(0)||y>f(100)) //比较端点函数值 { puts("No solution!"); continue; } else { left=0;right=100; while(right-left>1e-8) //对于double类型的值,应尽量减小误差 { mid=(left+right)/2; if(abs(f(mid)-y)<1e-8) break; if((f(mid)-y)>1e-8) right=mid; else left=mid; } } printf("%.4lf\n",mid); } return 0;}
例题二:
题目来源:HDOJ-2141:Can you find it?
题目大意:给你三个有序数列A, B, C,再给出一个数字 X. 能否找到三个数字Ai, Bj, Ck, 使得 Ai+Bj+Ck = X.
题目分析:最基础的二分查找问题,避免超时,进行优化,先合并两个数组再进行查找。
AC代码:
#include <stdio.h>#include <math.h>#include <algorithm>using namespace std;#define C 550int L[C],N[C],M[C];int LN[C*C];int find(int LN[],int k,int y) //二分查找{ int left=0,right=k-1,mid; while(left<=right) { mid=(left+right)/2; if(LN[mid]==y) return1; if(LN[mid]>y) right=mid-1; else left=mid+1; } return 0;}int main(){ int l,n,m,s,i,j,k; int num=1,x,y,q; while(~scanf("%d%d%d",&l,&n,&m)) { k=0; for(i=0;i<l;i++) scanf("%d",&L[i]); for(i=0;i<n;i++) scanf("%d",&N[i]); for(i=0;i<m;i++) scanf("%d",&M[i]); for(i=0;i<l;i++) for(j=0;j<n;j++) LN[k++]=L[i]+N[j]; //合并L和N sort(LN,LN+k); //对LN数组排序 scanf("%d",&s); printf("Case %d:\n",num++); while(s--) { q=1; // q为标记,1为找不到,0为能找到 scanf("%d",&x); for(i=0;i<m;i++) { y=x-M[i]; //因为L+N+M=x,所以x-M=LN=y if(find(LN,k,y)) //在LN数组中查找到y { puts("YES"); q=0; break; } } if(q) // 找不到y puts("NO"); } } return 0;}
例题三:
题目来源:HDOJ-1551:Cable master
题目大意:有n段长度不等的电缆,要求分成最大长度的k段长度相等的电缆
题目分析:基本的二分查找,寻找最合适的长度。
AC代码:
#include <stdio.h>double a[100100];int n,k,i;bool find(double x) //等长度的电缆段数是否符合要求,并且是否为最长的电缆{ int sum=0; for(i=0;i<n;i++) sum+=(int)(a[i]/x); return sum>=k;}int main(){ double left,right,mid; while(scanf("%d%d",&n,&k),n||k) { for(i=0;i<n;i++) scanf("%lf",&a[i]); left=0; right=100000; while(right-left>1e-8) //判断是否符合要求 { mid=(left+right)/2; if(find(mid)) //电缆不是最长 left=mid; else //电缆段数不够 right=mid; } right=(int)(right*100)/100.0; //right,mid,left都符合要求,但是right是最大的,更符合要求, printf("%.2lf\n",right); //而且不能四舍五入,防止电缆不够 } return 0;}
1 0
- 二分查找
- 二分查找
- 二分查找
- 二分查找
- 二分查找
- 二分查找
- 二分查找
- 二分查找
- 二分查找
- 二分查找
- 二分查找
- 二分查找
- 二分查找
- 二分查找
- 二分查找
- 二分查找
- 二分查找
- 二分查找
- 【POJ 3122】 Pie (二分+贪心)
- Android Fragment(四)---Fragment与Activity通讯
- Android开发从源码的角度理解Volley
- bzoj2002
- 滚轮滑动加载更多数据
- 二分查找
- [leetcode-268]Missing Number(c)
- arcgis api for javascript 距离与面积量算
- UIScrollView_UIPageControl
- CSS 制作3D魔方 爱的魔方给女(男)朋友一个感动
- 学习笔记——Java调用Oracle存储过程
- listView复用问题
- bias和variance
- java线程死锁实例