POJ 3061 二分 字首和or尺取法

2022-07-04 14:24:18 字數 1427 閱讀 2199

題目鏈結

題目大意:找到最短的序列長度,使得序列元素和大於s。

解題思路

兩種思路。

一種是二分+字首和。複雜度o(nlogn)。有點慢。

二分列舉序列長度,如果可行,向左找小的,否則向右找大的。

字首和預處理之後,可以o(1)內求和。

#include "

cstdio

"#include

"cstring

"int sum[100005

],n,s,a,t;

bool check(int

x)

return

false;}

intmain()

int l=0,r=n,ans=0

;

while(l<=r)

else l=mid+1

; }

printf(

"%d\n

",ans);

memset(sum,

0,sizeof

(sum));}}

二分法另一種是某本著名的日譯acm書介紹的尺取法。複雜度o(n)

這個方法很簡單。

①令l=1,先找一下滿足要求的第乙個長度(當然不一定是最優結果)。期間r++不停伸展。

②滿足了是吧,現在踢掉第乙個元素,令l++。從第二個元素看起,不符合要求繼續伸展r。更新一下ans。繼續踢第二個元素。

③踢踢踢,直到不能伸展r,且不符合要求,break。

這種方法只有乙個疑問點,就是r不往回移動,其結果一定是對的嗎?

考慮一下,l一直向右移動,r其實沒必要向左動了。r只有在不滿足條件的時候才向右,否則停在原位。

此時憑l的移動已經能找出所有可行的區間了。可以聯想一下滑動變阻器,固定r,滑動l。

#include "

cstdio

"#include

"cstring

"#include

"iostream

"using

namespace

std;

int a[100005

],n,s,l,r,t,sum,ans;

intmain()

if(ans==0x3f3f3f3f) printf("

0\n"

);

else printf("

%d\n

",ans);}}

13592296

neopenx

3061

accepted

548k

79ms

c++593b

2014-11-02 20:53:32

poj 3061 二分 or 尺取法

傳送門 problem 3061 馬上就要去上課了,先獻上二分ac 其餘的有空再補 題意 給定長度為 n 的整數數列 a 0,1,2,n 以及整數 s。求出總和不小於 s 的連續子串行的長度的最小值。如果解不存在,則輸出 0。題解 1 二分 由於所有的元素都大於 0 所以陣列a 的字首和sum 為遞...

字首和 二分

powered by ab in 局外人 拿洛谷的乙個例子記一下字首和。資料超過了1e5,故o n 2 的演算法又行不通,所以換二分 include typedef long long ll using namespace std ll n,m,l,r ll a 1000001 sum 100000...

POJ 3579 Median 尺取 二分

給n數字,x1,x2,xn,我們計算每對數字之間的差值 xi xj 1 i j n 我們能得到 c n,2 個差值,現在我們想得到這些差值之間的中位數。如果一共有m個差值且m是偶數,那麼我們規定中位數是第 m 2 小的差值。input輸入包含多測 每個測試點中,第一行有乙個nthen n 表示數字的...