【枚举】连续自然数和(jzoj 2102)

版权声明:欢迎借鉴,谢绝抄搬。 https://blog.csdn.net/ssllyf/article/details/86663340

连续自然数和

题目大意:

输出一个n,求出所有相加等于n的连续自然数序列

样例输入

10000

样例输出

18 142

297 328

388 412

1998 2002

数据范围限制

10 <= M <= 2,000,000

解题思路:

这道题的正解的时间复杂度是 o ( 2 n ) o\left ( \sqrt{2n} \right ) 但因为我太蒟了,所以只用了 o ( n / 2 ) o\left ( n/2 \right ) 的方法, o ( n / 2 ) o\left ( n/2 \right ) 的方法就是先枚举2~n/2+1然后把这些数字当做奇数序列的中心,若可以被n整除,就往左右两边分别扩(n/i-1)/2个数字(首先把自己的那一份去掉在平分两边),然后把两个数字的和当做偶数数列的中心,若可以被整除,就往左右分别扩n/(i+i-1)-1个数字(前面是两个相连的数,然后去掉一份,因为他的一份是两个数字,所以*2/2抵消)

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int n,l;
int main()
{
	scanf("%d",&n);
	for (int i=2;i<=n/2+1;i++)//一半以上是不可能的,但要到n/2+1例如5可以2+3(n/2+1)
	  {
	  	if ((n%i==0)&&((n/i)&1))//奇数数列判断是否整除,和是否有奇数份
	  	  {
	  	  	l=(n/i-1)/2;//往两边扩
	  	  	if (i>l&&i+l<n)//判断是否出界
	  	  	  printf("%d %d\n",i-l,i+l);
	      }
		if (n%(i+i-1)==0)//判断是否整除
		  {
		  	l=n/(i+i-1)-1;//往两边扩
		  	if(i>l+1&&i+l<n)//判断是否出界
		  	  printf("%d %d\n",i-l-1,i+l);//i-1占了一个位
		  }
	  }
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/ssllyf/article/details/86663340