バイナリ検索
(シモンズ:参考図書:課題プログラミング)
二分法検索:配列検索アルゴリズムの特定の要素を見つけるために、解決策が存在する範囲を縮小することによって。
二分法は、多くの場合、他のアルゴリズムのトピックと関連して見られています
アイデアの二分法:
位置の値が正確に目標である場合(1)まず、検索を終了し、見つけ、次に、アレイの中央から探索を開始します。
最初のステップは、値を検索する場合(2)よりも大きい標的配列に、半分にアレイを置く右へ、次いで工程(1)の動作を繰り返すこと、領域を見つけること。
最初のステップは、値が検索した場合未満である標的配列に、半分にアレイを置く左側の領域を見つけるために、その後、繰り返し工程(1)。
(3)配列を見つけることができない、まだ残りの要素に分割されている場合、それが意味を見つけることができません。
左から右への単純なを見つけ、時間がO(n)は、O(LOGN)のバイナリ検索時間があります。
次のように通常は大体書か:
//二分
int l=0,r=n; // l:左边 r:右边
while(l<=r){
int mid = (l+r)/2;
if(a[mid]== k){
cout<<mid;
break;
}
if(a[mid] > k){
r = mid-1;
}else{
l = mid+1;
}
}
の使用に関連します
より良い時間よりも、私は約L、上記のようにしている書いて、Rは、開始配列インデックスとテール指標です。
しかし、対象の性質のためにいくつかの問題は、これを行うことができない上に書いた(私は55が弱すぎたかもしれない)
:次のようになるように
、各指標を書くの通常の種類が前方または後方に移動させることである、で使用されています配列中に存在する数を求める
と、この問題は実数、配列に表示されない値を必要とすることです。
それをどのように行うには?Lであるべきで、Rは、応答として、そして次いでジエチルポイント要件の範囲です。
このような何かを書きます:
#include<iostream>
#include<cstdio>
using namespace std;
#include<cmath>
const int maxn = 10005;
int n,k;
double a[maxn];
bool f(double x){
int cnt=0;
for(int i=1;i<=n;i++){
cnt += (int)(a[i]/x);
}
return cnt>=k;
}
int main(){
cin>>n>>k;
double len = 0;
for(int i=1;i<=n;i++){
cin>>a[i];
len += a[i];
}
// 二分
double l =0,r = len;
for(int i=0;i<100;i++){
double mid = (l+r)/2;
if(f(mid)){
l = mid;
}else{
r = mid;
}
}
// cout<<l-1;
printf("%.2f",l);
return 0;
}
この二分法、L、Rの値は、もはや標準左が、ターゲットの回答の左と右の範囲ではありません
テンプレートを書きます:
// 二分
int l =-1,r = n;
while(r-l>1)
int mid = (l+r)/2;
if(a(mid) >=k){ //如果解满足条件,则解存在的范围变为(l,mid]
r = mid;
}else{
l = mid; //如果解不满足条件,则解存在的范围变为(mid,r]
}
}
cout<<r;
問題の最小範囲を最大化
最小値、最大値、平均最大化、最小化、最大化と同様に、あなたは通常、バイナリ検索、使用する必要があります
など、これを以下、それを言うことはありませんどのように他の、ほぼ同じに。
#include<iostream>
#include<cstdio>
using namespace std;
#include<algorithm>
const int maxn = 100005;
int n,m;
int x[maxn];
bool f(int d){
int last = 0;
for(int i=1;i<m;i++){
int k=last+1;
while(x[k] - x[last] <d && k<n){
k++;
}
if(k ==n){
return false;
}
last = k;
}
return true;
}
int main(){
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>x[i];
}
sort(x,x+n);
int l=0,r=1e8;
while(r-l>1){
int mid = (l+r)/2;
if(f(mid)){
l = mid;
}else{
r = mid;
}
}
cout<<l;
return 0;
}