输入一个长度为n的序列,并输入左序列区间端点l及右序列区间端点r,求出l与r之间的数的和。
通常来讲我们在数据不大的情况下会直接暴力求解
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n, l, r, sum = 0;
scanf("%d%d%d",&n,&l,&r);
for ( int i = l; i <= r; i++ )
{
sum += i;
}
printf("%d",sum);
return 0;
}
然而众所周知,数据一大暴力就会翻车,因此就有了前缀和,前缀和可以大大减小算法的时间复杂度
贴上洛谷一道题
求连续自然数和与指定值相等。
数据量不大,所以先通过一个for循环将和的数值贮存在一个数组里面,然后再通过遍历来寻找符合的值输出相应的l与r即可。
贴上代码
#include<bits/stdc++.h>
using namespace std;
int s[2000001];
int main()
{
int m;
scanf("%d",&m);
for ( int i = 1; i <= 2000000; i++ )
s[i]=s[i-1]+i;
for ( int i = 1; i < m; i++ )
{
for ( int j = i+1; j <= m; j++)
{
if ( s[j] - s[i-1] == m ) printf("%d %d\n",i,j);
else if ( s[j] - s[i-1] > m ) break;
}
}
return 0;
}
值得注意的是这段。
else if ( s[j] - s[i-1] > m ) break;
因为第一次提交没写这段所以tle了
这段代码可以减少很多不必要的遍历