日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

(二分搜索法尺取法)subsequence

發(fā)布時(shí)間:2025/3/12 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (二分搜索法尺取法)subsequence 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目

A sequence of N positive integers (10 < N < 100 000), each of them less than or equal 10000, and a positive integer S (S < 100 000 000) are given. Write a program to find the minimal length of the subsequence of consecutive elements of the sequence, the sum of which is greater than or equal to S.
Input
The first line is the number of test cases. For each test case the program has to read the numbers N and S, separated by an interval, from the first line. The numbers of the sequence are given in the second line of the test case, separated by intervals. The input will finish with the end of file.
Output
For each the case the program has to print the result on separate line of the output file.if no answer, print 0.
Sample Input
2
10 15
5 1 3 5 10 7 4 9 2 8
5 11
1 2 3 4 5
Sample Output
2
3

分析與解答

題意:給出長度為n的數(shù)列以及整數(shù)s,求出總和不小于s的連續(xù)子序列長度的最小值,如果不存在,輸出0

方法一:尺取法

尺取法原理;
假設(shè)a1+a2+…+a4>s
此時(shí)說明a2+a3< a1+a2+a3< s
那么如果我們想繼續(xù)向前找,a2+a3+…+at>s。t一定是大于等于4
這說明,如果依次尋找,不用考慮中間點(diǎn)的影響,決定子序列是否滿足條件的是他的兩個(gè)端點(diǎn),因此我們可以通過對兩個(gè)端點(diǎn)的調(diào)控,達(dá)到遍歷找出答案的目的
1.表示方法:
我們用數(shù)組存數(shù)據(jù),sum存子序列和,然后用i表示左端點(diǎn),t表示右端點(diǎn)
2.調(diào)控方法:
右端點(diǎn)向右移動,那就是t++,移動之后,sum+a[t]
左端點(diǎn)向右移動,就是i++,移動之后,sum-a[i]

3.移動條件:
sum< s,右端點(diǎn)移動,左端點(diǎn)不動
sum>s,左端點(diǎn)移動,右端點(diǎn)不動
4.模擬過程:

void solve(){int res=n+1;int i=0,t=0,sum=0;for(;;){while(t<n&&sum<s){sum+=a[t++];}if(sum<s) break;res=min(res,t-i);sum-=a[i++];}if(res>n){res=0;}printf("%d\n",res); }

ac代碼

#include <iostream> #include <algorithm> #include <cstring> #include<cstdio> using namespace std; const int mm=100010; int a[mm]; int n,s;void solve(){int res=n+1;int i=0,t=0,sum=0;for(;;){while(t<n&&sum<s){sum+=a[t++];}if(sum<s) break;res=min(res,t-i);sum-=a[i++];}if(res>n){res=0;}printf("%d\n",res); }int main(){int t;cin>>t;while(t--){memset(a,0,sizeof(a));cin>>n>>s;for(int i=0;i<n;++i){cin>>a[i];}solve();} }

二分搜索法

我們想想,既然是連續(xù)子序列,那么可以通過前綴數(shù)組表示出所以子序列可能情況,我們只需找出滿足條件的情況,進(jìn)行判斷然后輸出就可以了
對于這一題,如果在i到n中有一個(gè)t,使得sum[t]-sum[i]>=s,那t-s就是他們之間的元素個(gè)數(shù),所以我們只需找t,利用lower_bound,
我第一次用的是這個(gè)方法,用畫圖的方法,要搞清楚他的區(qū)間

sum[i]是從1開始存的,有人問那個(gè)循環(huán)為啥是從零開始,
因?yàn)檠h(huán)從零開始是找有沒有sum[i]直接就等于s了
循環(huán)從1開始的話,就正式找sum[t]了

#include <iostream> #include <algorithm> #include <cstring> #include<cstdio> using namespace std; const int mm=100010; int a[mm]; int sum[mm]; int n,s;void solve(){for(int i=0;i<n;++i){sum[i+1]=sum[i]+a[i];}if(sum[n]<s){printf("0\n");return ;}int res = n;for(int i=0;sum[i]+s<sum[n];++i){int t=lower_bound(sum+i,sum+n,s+sum[i])-sum;res=min(res,t-i);}printf("%d\n",res); }int main(){int t;cin>>t;while(t--){memset(a,0,sizeof(a));memset(sum,0,sizeof(sum));cin>>n>>s;for(int i=0;i<n;++i){cin>>a[i];}//sum[0]=0;solve();} }

總結(jié)

以上是生活随笔為你收集整理的(二分搜索法尺取法)subsequence的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。