【做题笔记】洛谷P1147连续自然数和

裸的前缀和啊。

(mathcal{O}(n^2)) 枚举有可能的答案,利用前缀和的性质维护答案即可

但是 (m) 的范围很大,需要加入剪枝:

  1. (i,j) 枚举的范围 [1,m] 就好了,因为若 (i,j) 大于 (m) 那么必然得不到答案;
  2. 找到一个答案就退出一次循环,因为不可能再找到以 (i) 为左端点的另一个答案;
  3. 如果当前情况已经大于 (m) 就退出一次循环,因为既然 [i,j] 都大于 (m) ,那么 [i,j+?] 也必然大于 (m)

之所以可以这样干是因为要求找的是单调上升自然数连续数列。

另外,j 每次的循环范围应从 i+1 开始,因为若 (j<i) ,那么一定得不到答案(每次相减都会是负数)。这样做既加快了速度,也可以保证答案不重不漏。

#include <iostream>
#include <stdio.h>

using namespace std;

int pre[20000010],m;

int main()
{
	cin>>m;
	for(int i=1;i<=m;i++) pre[i]=i+pre[i-1];
	for(int i=1;i<=m-1;i++)
		for(int j=i+1;j<=m;j++)
		{
			if(pre[j]-pre[i-1]==m)
			{
				cout<<i<<" "<<j<<endl;
				break;
			}
			if(pre[j]-pre[i-1]>m) break;
		}
	return 0;
}
原文地址:https://www.cnblogs.com/BlueInRed/p/12404527.html