二分法即折半查找:要求数组为有序排列 left right mid 主要代码:
while(left<=right)
{
mid=(left+right)/2;
if(m[mid]>x)
right=mid-1;
if(m[mid]<x)
left=mid+1;
if(m[mid]==x)
break;
}
代码来自 大哥的csdn
http://acm.sdibt.edu.cn/vjudge/contest/view.action?cid=2015#problem/G
题意: 输入一个实数,求x,使得8*x^4 + 7*x^3 + 2*x^2 + 3*x + 6 = Y成立,x的范围为[0,100],否则输出“No solution!”。
题解: 二分思想,x在[0,100]之间不断二分查找,直至找到结果
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
const double N=1e-8;//这里数不能太大,否则精度会出错
double coun(double x)
{
return 8*x*x*x*x+7*x*x*x+2*x*x+3*x+6;
}
int main()
{
int T;
double y,s0=coun(0),s100=coun(100.0);
scanf("%d",&T);
while (T--)
{
scanf("%lf",&y);
if (y<s0||y>s100)
{
printf("No solution!\n");
continue;
}
double l=0,r=100,mid;
int flag=0;
//while (fabs(coun(mid)-y)>N)两个判断条件都可以,不过mid的位置有稍微的改变
while (r-l>N)
{
mid=(l+r)/2;
if(coun(mid)>y)
r=mid;
else
l=mid;
}
printf("%.4lf\n",mid);
}
return 0;
}
http://acm.sdibt.edu.cn/vjudge/contest/view.action?cid=2015#problem/J
Description
给你一个序列,然后给你m个元素,让你从序列中找出与每个元素最接近的数字输出来,如果有两个就输出两个。
Input
多组输入,第一行给你两个数n(0 < n < 10000000),m(0 < m < n),接下来是数列的n个数,然后再输入m个元素,让你找出最接近每个元素的值。如果有两个,按从小到大输出。
Output
这m个数分别输出最接近每个元素的值,组与组之间输出一个空行。
Sample Input
8 4 1 2 3 4 5 6 8 11 4 9 2 7
Sample Output
4 8 2 6 8
题解: 输入一串序列,排序为升序排列,分别从左边找小于目标数且接近目标数的数的下标d,和从右边找大于目标数且接近目标数的数的下标u,a[u]和a[d]两个数进行比较,输出答案
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=1e7+7;
int a[N];
//找小于目标的数且最接近目标数的数
//因为找小于目标数的数,所以要从左边不断地接近目标数
int down(int left,int right,int t)
{
int mid,index=-1;
while (left<=right)
{
mid=(left+right)/2;
if (a[mid]<=t)
{
left=mid+1;
index=mid;
}
else right=mid-1;
}
return index;
}
//找大于目标的数且最接近目标数的数
//因为找大于目标数的数,所以要从右边不断地接近目标数
int up(int left,int right,int t)
{
int mid,index=-1;
while(left<=right)
{
mid=(left+right)/2;
if (a[mid]<=t)
left=mid+1;
else
{
right=mid-1;
index=mid;
}
}
return index;
}
int main()
{
int n,m,t;
while (~scanf("%d %d",&n,&m))
{
for (int i=0; i<n; i++)
scanf("%d",a+i);
sort(a,a+n);//升序
while (m--)
{
scanf("%d",&t);
int d=down(0,n-1,t);
int u=up(0,n-1,t);
if (d==-1)//没有左边的数
printf("%d\n",a[u]);
else if (u==-1)//右边没有数
printf("%d\n",a[d]);
else if (a[d]==a[u])//左边和右边找到的一样,那就是找到了
printf("%d\n",a[u]);
else
{
if (t-a[d]<a[u]-t)//左边的数都更接近目标数
printf("%d\n",a[d]);
else if (t-a[d]>a[u]-t)//右边的数更接近目标数
printf("%d\n",a[u]);
else //左边的数和右边的数一样接近目标数
printf("%d %d\n",a[d],a[u]);
}
}
printf("\n");
}
return 0;
}