来自https://ac.nowcoder.com/acm/problem/15553
先是read()函数,用于快速读入,比cin快,比printf快
int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-'){
f=-1;
}
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
调用函数的时候定义一个新变量
比如输入一个T,表示测试次数
int T;
T=read();
接下来是看题干,两个不连续的区间
区间长度为k
int main(){
ll t,a;
ll ans[200005];
ll sum[200005];
cin>>t;
memset(ans,-0x7f,sizeof(ans));//0x7f??
memset(sum,0,sizeof(sum));
while(t--){
ll n,k,res=-1e18;
n=read();k=read();
for(int i=1;i<=n;i++){
a=read();
sum[i]=sum[i-1]+a;
}
for(int i=n-k+1;i>k;i--){
ans[i]=max(ans[i+1],sum[i+k-1]-sum[i-1]);
res=max(res,ans[i]+sum[i-1]-sum[i-k-1]);
}
cout<<res<<endl;
}
return 0;
}
用一个sum[i]表示前i个数的和,这样区间[l,r]可以用sum[r-1]-sum[l-1]表示。
这种开数组的做法避免了遍历ai求和的过程(优化)。
然后自右向左,比较[i,k]的区间中的成绩和,取最大的存入ans[i]中,定义一个res为最后结果,取i左边最大的区间和右边最大的区间和。
右边最大的区间为ans[i] (sum[i+k-1] - sum[i-1]) ,左面最大的为sum[i-1] - sum[i-k-1].
再解释一下,就是ans[i]的部分在通过遍历寻找右面区间的最大值,然后如果有更大的就顶替掉原来的ans[i],不然就ans[i]=ans[i+1]继续保持最大结果。i左边的区间同理。最后用res存和最大的情况,输出。