二分查找的基本应用----求方程的根&输入n个整数 ,找出其中两个数之和等于整数m

//例:y=x3-5x2+10x-80
//对y求导,y’=3x^2+10x+10,y’恒大于0,因此y是单调递增的,
//因此可以运用二分查找来 逐渐所小范围,找到方程的近似根

#include<bits/stdc++.h>
using namespace std;
double MIN=1e-6;//10^-6 ,相当于0 
int B(double x)
{
	return x*x*x-5*x*x+10*x-80;
}
int main()
{
	double t,x1=0,x2=100,y;//x1,x2,由题确定,不会影响近似值的求取 
	t=x1+(x2-x1)/2;
	y=B(t);//y更新当前的中间值
	while(fabs(y)>MIN){
		if(y>0) x2=t;//移动x2,向下,向x轴逼近 
		else x1=t;//移动 x1,向上,向x周逼近 
		t=x1+(x2-x1)/2;//新的中间x坐标 
		y=B(t);//重复更新中间值 
	} 
	cout<<t<<endl;
	return 0;
}

//输入n个整数 ,找出其中两个数,它们之和等于整数m

#include<bits/stdc++.h>
#define MAXSIZE 10001
using namespace std;
int a[MAXSIZE];
int BinarySearch(int a[], int n, int k)
{
	int L=0;
	int R=n-1;
	int flag=0;
	while(L <= R)
	{
		int mid=L+(R-L)/2;
		if(a[mid]==k)  
		{
			flag=1;
			break;
		}
		else if(a[mid]>k)
		{
			R=mid-1;
			}
		else
			L=mid+1;
	}
	return flag;
}
int main()
{
	int n,m,flag=0,i;
	cout<<"请输入要查找的数字m及数组长度n:";
	cin>>m>>n;
	cout<<"请输入数组元素:"; 
	for(i=0;i<n;i++){
		cin>>a[i];
	}
	sort(a,a+n);//排序库函数
// I)sort函数包含在头文件为#include<algorithm>的c++标准库中
//II)sort函数有三个参数:
//形式:sort(first_pointer,first_pointer+n,cmp)
//bool cmp(int a,int b)
//{
//	return a>b;//降序
//  return a<b;//升序 
//} 
//(1)第一个是要排序的数组的起始地址。
//(2)第二个是结束的地址(最后一位要排序的元素地址+1即n)
//(3)第三个参数是排序的方法,可以是从大到小也可是从小到大,还可以不写第三个参数,此时默认的排序方法是从小到大排序。
	for(i = 0; i < n; ++ i)
	{
		int k = m - a[i];
		if(BinarySearch(a,n,k))
		{
			flag = 1;
			if(a[i] == k && a[i] == a[i+1]) //注意两个数相等,并且和刚好为m的情况,此时只需要输出一组数据即可 
			{
				cout<<a[i]<<" "<<k<<endl;
				break;//两个数相等,并且和为m,则这个数后面的数字和如果要等于m,肯定比m大的,直接跳出循环 
			}
			if(a[i] >= m/2) break;//判断是否全找完,当a[i]>=m/2时,表示往后的元素的和要等于m,则必为与前面元素重复,
			//也就么有继续遍历数组的必要了 
			cout<<a[i]<<" "<<k<<endl;			
		}	 
	}
	if(!flag)
		cout<<"Can't Found!"<<endl;
	return 0;
}

//还可以这样做
//利用排序好的数组,每个元素只对应了一个元素与它和为m
//因此可以从两边同时遍历数组向中间逼近,最后找到和为m的元素直接输出

#include<bits/stdc++.h>
#define MAXSIZE 10001
using namespace std;
int a[MAXSIZE];
int main()
{
	int n,m;
	cout<<"请输入要查找的数字m及数组长度n:";
	cin>>m>>n;
	cout<<"请输入数组元素:"; 
	for(int i=0;i<n;i++){
		cin>>a[i];
		}
	sort(a,a+n);//同上 
	int i=0;
	int j=n-1;
	int flag = 0;
	while(i<j)//不能加等号,否则会出现输出m/2的情况
	{
		int k=a[i]+a[j];
		if(k==m)
		{
			cout<<a[i++]<<" "<<a[j--]<<endl;//相等时i和j要更新否则会一直循环 
			flag=1;
		 } 
		else if(k>m)//说明a[j]太大了 
			j--;
		else 
			i++; 
	}	
	if(!flag){ 
		cout<<"Can't Found!"<<endl;
		} 
		return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值