链接:https://ac.nowcoder.com/acm/contest/11211/F
来源:牛客网
题目描述
读入n,x,给出n个数a[1],a[2],……,a[n],求最小的区间[l,r],使a[l]+a[l+1]+……+a[r]≥x,若存在相同长度区间,输出l最小的那个
输入描述:
第一行两个数,n(1≤n≤10000000),x(1≤x≤10000)
第二行n个数a[i](1≤a[i]≤1000)
输出描述:
输出符合条件l,r(保证有解)
示例1
输入
10 20
1 1 6 10 9 3 3 5 3 7
输出
3 5
错误答案:
直接暴力枚举,每次计算和之后更新值,找出符合条件的,进行输出,但是会超时,能过样例,但不能AC。
#include<iostream>
using namespace std;
int a[100000050]={0},sum[100000050]={0};
int main() {
int n,x;
cin>>n>>x;
for(int i=0; i<n; i++)
cin>>a[i];
int c,b,i,j;
int s=1050,l=1050;//初始化所找区间长度的最大值
for(i=0; i<n; i++) {
for(j=i; j<n; j++) {
sum[i]+=a[j];//计算各数之和
if(sum[i]>=x) {
l=j-i;//找到之后,计算每次的区间长度
break;
}
}
if(l<s) {
s=l;//找到更小的区间长度就更新值
c=i+1;
b=j+1;//标记每次符合条件的起始位置
}
}
cout<<c<<" "<<b;//输出"l","r".
}
正确样例:
思路:但是可以用前缀和进行优化,所以就直接换了思路。
AC代码:
#include<stdio.h>
int main(){
int a,b,sum=0,z=0,y=0,q=99999,j=1;//初始化需要的变量
scanf("%d %d",&a,&b);
int x[a+1];
for(int i=1;i<=a;i++){
scanf("%d",&x[i]);
sum=sum+x[i];
//利用前缀和,得出第一个满足条件的点
while(sum>=b){
if(i-j<q)//对比符合条件的区间长度
{
q=i-j;//更新每一次能满足条件的区间长度
z=j;
y=i;
}
sum=sum-x[j++];
//利用简单的运算依次相减,得出最小的区间
}
//因为是采用前缀和的计算方法,所以先得出的区间位置肯定比后面大的,即位置的大小
}
printf("%d %d",z,y);//输出即可
return 0;
}