二分常用於在一段序列中尋找某一段符合條件的序列返回其區間範圍,否則返回null或特殊值
該序列一般具有單調性(沒有單調性的序列也可以使用二分,但不常用)
序列一定具有二段性,即在查詢中可以分為兩半,一半暫時符合條件,一半暫時不符合條件
題目一半要求找乙個有序序列裡某一段值
步驟找乙個區間【l,r】,使得答案一定在區間中
找乙個判斷條件,使得區間具有二段性,並且答案一定會出現在該二段的分界點
判斷中點mid是否符合該判斷條件,考慮答案在哪個左右哪個區間
如果更新mid的方式是l=mid,則更新mid時需要再加上1即mid = (l + r + 1 ) / 2 ,防止程式進入死迴圈
模板(對應上面的步驟)
設定區間 l = ***, r = ***;
迴圈while(l < r)
if判斷,根據判斷的條件更新 l 或 r縮小區間,使得答案一定在[l,r]之間
實數二分基本步驟與整數二分一致,只是實數二分不需要考慮mid在更新時是否需要加一,直接寫mid = (l + r ) / 2;
題目:
**:
#include
#include
using
namespace std;
const
int n =
100010
;int n,m,q[n]
;int
main()
for(
int i =
0;i < m;i ++
)//二分右端點
//如果存在左端點
if(q[l]
== x)
cout << r << endl;
}else cout <<
"-1 -1"
<< endl;
}return0;
}
題目:
**:
#include
#include
using
namespace std;
intmain()
printf
("%lf"
,l);
return0;
}
木材廠有一些原木,現在想把這些木頭切割成一些長度相同的小段木頭,需要得到的小段的數目是給定的。當然,我們希望得到的小段越長越好,你的任務是計算能夠得到的小段木頭的最大長度。木頭長度的單位是厘公尺。原木的長度都是正整數,我們要求切割得到的小段木頭的長度也要求是正整數。
lnput:
第一行是兩個正整數n和k(1≤n≤10000,1 ≤ k ≤ 10000),
n是原木的數目,k是需要得到的小段的數目。
接下來的n行,每行有乙個1到10000之間的正整數,表示一根原木的長度。
output:
輸出能夠切割得到的小段的最大長度。如果連1厘公尺長的小
段都切不出來,輸出"o"』。
示例輸入:
3 7232
124456
輸出 : 114
**:
#include
#include
using
namespace std;
const
int n =
10010
;int n,m;
int mood[n]
;int
main()
//二分
int l =
1,r =(*
max_element
(mood,mood+n));
//用於記錄已經分割到第幾根了
int num =
0,ans =0;
while
(l < r)
if(num < m) r = mid -1;
else
} cout << ans << endl;
return0;
}
題目:
思路:**:
#include
using
namespace std;
const
int n =
1e5+10;
int n,k,h[n]
,w[n]
;//判斷正方形長度x是否能夠分割出k塊
bool
check
(int mid)
return
false;}
intmain()
//二分
int l =
0,r =
1e5;
while
(l < r)
cout << r;
return0;
}
二分 藍橋杯省賽 分巧克力
題目 兒童節那天有 k 位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友們。小明一共有 n 塊巧克力,其中第 i 塊是 hi wi 的方格組成的長方形。為了公平起見,小明需要從這 n 塊巧克力中切出 k 塊巧克力分給小朋友們。切出的巧克力需要滿足 形狀是正方形,邊長是整數 大小相同 例如一塊 ...
基礎 二分演算法學習筆記
1 二分的基本用法是在單調序列或單調函式中進行查詢。2 當問題的答案具有單調性時,就可以通過二分把求解轉化為判定 判定一般比求解容易實現。這裡都是個人寫法,可以跳過 1 整數域 1 原則 2 流程 分析問題,確定左右半段哪個是可行區間,以及mid歸屬哪一半。選擇寫法 l mid還是r mid l r...
基礎 二分演算法學習筆記
1 二分的基本用法是在單調序列或單調函式中進行查詢。2 當問題的答案具有單調性時,就可以通過二分把求解轉化為判定 判定一般比求解容易實現。這裡都是個人寫法,可以跳過 1 整數域 1 原則 2 流程 分析問題,確定左右半段哪個是可行區間,以及mid歸屬哪一半。選擇寫法 l mid還是r mid l r...