思想:将较大规模的问题分解成几个较小规模的问题
例题一、找数
给一个长度为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);
}