Subsequence / UVA - 1121
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
Many test cases will be given. 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.
Sample Input
10 15
5 1 3 5 10 7 4 9 2 8 5 11
12345
Sample Output
2 3
题意
输入n s:在n个数,在其中找最小长度的连续子序列,子序列要满足大于S,求最小值
题解
二分查找 & 前缀和
sum[i]前i个数的和, 二分枚举所有子序列
尺取法
枚举左 右端点,找不同左端点时,满足条件的最小长度
代码
二分 & 前缀和
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 1e5+10;
int n, s, sum[N];
int main(){
while(scanf("%d%d", &n, &s) == 2){
int x;
memset(sum, 0, sizeof(sum));
for(int i = 1; i <= n; i++){
scanf("%d", &x);
sum[i] = sum[i-1] + x;//初始化sum[], 前缀和
}
int ret = N;
int left, right, mid, best;
for(int i = 1; i <= n; i++){//枚举一遍
left = i, right = n, best = 0;
while(left <= right){//二分查找
mid = (left+right) / 2;
if(sum[mid] - sum[i-1] >= s){
best = mid, right = mid - 1;
}else{
left = mid + 1;
}
}
if(best){//best-i+1 -> 子序列的长度
if(best-i+1 < ret){
ret = best - i + 1;
}
}
}
if(ret != N){
printf("%d\n", ret);
}else{
printf("0\n");
}
}
return 0;
}
PS
while(scanf("%d%d", &n, &s) == 2)//如果成功读入了2个数的话
不能写成
while(scanf("%d%d", &n, &s))
尺取法
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int n, s, a[N];
int main(){
while (scanf("%d%d", &n, &s) == 2){
for(int i = 1; i <= n; i++){
scanf("%d", &a[i]);
}
int j = 0, tmp = 0, ret = N;
for(int i = 1; i <= n; i++){//枚举尺子的左端点
while (j < n && tmp < s){//枚举尺子长度,直到尺子最长或满足条件(区间和 < s)
j++;
tmp += a[j];
}
if(tmp >= s){
ret = min(ret, j - i + 1);
}
tmp -= a[i];//左端点往右移一位,最左端的就去掉
}
if(ret != N){
printf("%d\n", ret);
}else{
printf("0\n");
}
}
return 0;
}
PS
尺取法顾名思义,核心就是一把尺子。
本题中先不断枚举尺子的左端点,然后枚举尺子的长度,找最小的即可
没有未来的未来不是我想要的未来

浙公网安备 33010602011771号