C++基础算法——分治算法

思想:将较大规模的问题分解成几个较小规模的问题

例题一、找数

给一个长度为n的单调递增的正整数数列,有m个询问,每次询问序列中最后一个小于等于x的数是什么?

输入:

n m

数列

询问的数字

二分法

cpp 复制代码
#include<iostream>
using namespace std;
int main(){
	int n,m,a[110000];
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>a[i];
	a[0]=-1;
	for(int i=1;i<=m;i++){
		int x;
		int left=1,right=n,mid;
		cin>>x;
		while(left<=right){
			mid=(left+right)/2;
			if(a[mid]<=x)left=mid+1;
			else right=mid-1;
		}
		cout<<a[right]<<endl;
	}
	return 0;
}

例题二、快速排序

cpp 复制代码
#include<iostream>
using namespace std;
void qsort(int ,int );
int a[101];
int main(){
	int n,i;
	cin>>n;
	for(i=1;i<=n;i++){
		cin>>a[i];}
	qsort(1,n);
	for(i=1;i<=n;i++)
		cout<<a[i]<<" ";
	cout<<endl;
}
void qsort(int l,int r){
	int i,j,mid,p;
	i=l;j=r;
	mid=a[(l+r)/2];
	do{
		while(a[i]<mid)i++;
		while(a[j]>mid)j--;
		if(i<=j){
			p=a[i];a[i]=a[j];a[j]=p;
			i++;j--;
		}
	}while(i<=j);
	if(l<j)qsort(l,j);
	if(i<r)qsort(i,r);
}

例题三、解一元三次方程

ax^3+bx^2+cx+d=0,输入a,b,c,d,已知根在-100到100之间,且相邻两根的差的绝对值>=1

思路:利用零点存在定理,整数x遍历-100到100,每次+1,其中x1=x,x2=x+1,若根在x1和x2之间,对此区间做二分法

cpp 复制代码
#include<stdio.h>
double f(double,double,double,double,double);
int main(){
	double a,b,c,d;
	scanf("%d %d %d %d",&a,&b,&c,&d);
	int x;
	double x1,x2,xx;
	for(x=-100;x<=100;x++){
		x1=x;x2=x+1;
		if(f(x1,a,b,c,d)==0)printf("%.2f",x1);
			else if(f(x1,a,b,c,d)*f(x2,a,b,c,d)<0)
			{
				while(x2-x1>=0.001){
					xx=(x2+x1)/2;
					if(f(x1,a,b,c,d)*f(xx,a,b,c,d)<=0)
						x2=xx;
						else x1=xx;
				}
				printf("%.2f",x1);
			}
	}
	printf("\n");
}
double f(double x,double a1,double b1,double c1,double d1){
	return (x*x*x*a1+b1*x*x+c1*x+d1);
}