原題鏈接
題目不再描述了。
方法: 尺取法(追逐法)
a 爲 正數 數組
設子序列
左端點爲 i
右端點爲 j
sum 爲 子序列 的 和。
{
如果 sum 大於等於 s,
i 右移 sum 更新(sum 變小);
如果 sum 小於 s,
j 右移 sum 更新(sum 變大);
}
不斷循環此過程 即可。
具體 C語言代碼 如下(用 C++ 提交 )
#include<stdio.h>
int main(){
int N, n, s;
int a[100000];
scanf("%d", &N);
while(N--){
int sum = 0, i, j;
scanf("%d%d", &n, &s);
int len = n; //len 爲 最短子序列 的長度 假設存在 初始化爲n (便於更新)
for(i = 0; i < n; i++){
scanf("%d", &a[i]);
sum += a[i]; //sum 爲 數組累加和
}
if(sum < s) printf("0\n"); // 特殊情況 不存在 子序列
else {
i = 0;
j = 0; // 左右端點 的 初始化
sum = a[0]; // sum爲 當前子序列的 長度
while( 1 ){
if(sum >= s) {
len = len < (j - i +1) ? len : (j - i + 1); // len 始終記錄 最短子序列 的 長度
if(len == 1) break; //最短子序列長度 最小爲 1 len爲1 直接結束循環
sum -= a[i]; // sum 更新
i++; // 左端點 右移
if( i > n-1) break; // i 超界 結束循環
}
else {
j++; // 右端點 右移
if(j > n-1) break; // j 超界 結束循環
sum += a[j]; // sum 更新
}
}
printf("%d\n", len); // 打印結果
}
}
}