二分查找
L左
R右
查找条件:while( L<=R )
#include<iostream>
#include<math.h>
#include<string>
using namespace std;
int Search(int a[],int n,int p);
int LowerBound(int a[],int n,int p);
int main(){
int n,a[100],p;
scanf("%d",&n);
for(int i=0; i<n; i++) cin >> a[i];
scanf("%d",&p);
return 0;
}
//给定数组 找其中的某个元素
int Search(int a[],int n,int p){
int l=0;
int r = n-1;
while(l<=r){
int mid = (l+r)/2;
if(p==a[mid]) return mid;
else if(p>a[mid]) l = mid+1;
else r = mid-1;
}
return -1;
}
//寻找从小到大int数组里 比给定整数p小的,下标最大的元素
int LowerBound(int a[],int n,int p){
int LastPos = -1;
int L = 0,R = n-1;
while(L<=R){
int mid = (L+R)/2;
if(a[mid]>=p){
R = mid-1;
}else{
LastPos = mid;
L = mid + 1;
}
}
return LastPos;
}
/*
注意:
1:有序
2.防止(L+R)/2 L+R溢出 采用L+(R-L)/2
*/
#include<iostream>
#include<math.h>
#include<string>
using namespace std;
double f(double x){
return x*x*x - 5*x*x + 10*x - 80;
}
double EPS = 1e-6;
int main(){
double root,x1=0,x2=100,y;
root = x1 + (x2-x1)/2;
y = f(root);
while(fabs(y)>EPS){
if(y>0) x2=root;
else x1=root;
root = x1 + (x2-x1)/2;
y = f(root);
}
cout << root << endl;
return 0;
}
找一对数
输入n (n<=100,000)找出其中两个数,使得他们之和等于m(假设肯定有解)
数据大:优化算法
解法1:
穷举:O(n^2)100亿
一般 :(oj)
一亿:危险
几百万:没问题
解法2:
步骤
1.排序:好的办法,快速排序:nlog n
2.查找 对每一个元素a[i] 再从数组中二分查找m-a[i] 看能否找到 O(logn)
整个查找复杂度:n-2logn
#include<iostream>
#include<math.h>
#include<algorithm>
using namespace std;
int Search(int a[],int l,int n,int p);
int main(){
int n,a[100000],x1,x2,m;
cin >> n;
for(int i=0; i<n; i++) cin >> a[i];
sort(a,a+n);
cin >> m;
for(int i=0; i<n; i++){
x1 = a[i];
x2 = m - x1;
if(Search(a,i,n,x2)>=0) cout << x1 << " + " << x2 << " = " << m <<endl;
}
return 0;
}
int Search(int a[],int l,int n,int p){
int r = n-1;
while(l<=r){
int mid = (l+r)/2;
if(p==a[mid]) return mid;
else if(p>a[mid]) l = mid+1;
else r = mid-1;
}
return -1;
}
解法3:
1.数组排序 n*logn
2.i 0 j n-1
a[i]+a[j] > m j—-
a[i]+a[j] < m i++
O(n)
#include<iostream>
#include<math.h>
#include<algorithm>
#include<queue>
using namespace std;
int main()
{
int n,a[100000],m;
cin >> n;
for(int i=0; i<n;i++) cin >> a[i];
cin >> m;
sort(a,a+n);
int L=0,R=n-1;
while(L<R){
if(a[L]+a[R]==m){
cout << a[L] << " + " << a[R] << " = " << m << endl;
}
if(a[L]+a[R]>m) R--;
else L++;
}
}
首先要注意自己犯过的错:不是多组输入
看好题目!
其次 多次提交报错,要学会看报错信息!
sqrt函数 是double sqrt(double)
#include<iostream>
#include<algorithm>
#include<string>
#include<math.h>
using namespace std;
#define M 505
//#define F(x) x*(x+1)/2
int main(){
int n;
cin >> n;
int L,R,mid,A,B;
bool flag = false;
//枚举左端点,对右端点二分
//for内,左端点固定的是i 右边的每次往左移动
for(int i=1; i<=int(sqrt(double(2*n))); i++){
L = i;
R = int(sqrt(double(2*n)));
mid = (L+R)/2;
A = i*(i+1)/2;
while(L<=R){
B = mid*(mid+1)/2; //中间和
if(A+B<n){
L = mid + 1;
mid = (L+R)/2;
}
else if(A+B>n){
R = mid - 1;
mid = (L+R)/2;
}
else{
flag = true;
break;
}
}
if(flag) break;
}
if(flag) cout << "YES" << endl;
else cout << "NO" << endl;
return 0;
}
/*
之前自己从来没有意识到的错误!!
double sqrt(double)!!!
*/