双指针思想,c语言.对一个给定的自然数M,求出所有的连续的自然数段,这些连续的自然数段中的全部数之和为M

问题导入

对一个给定的自然数M,求出所有的连续的自然数段,这些连续的自然数段中的全部数之和为M。

例如:1998 + 1999 + 2000 + 2001 + 2002 = 10000,所以从1998到2002的一个自然数段为M = 10000的一个解。

输入格式

        第一行,一个整数M。

输出格式

        每行两个自然数,给出一个满足条件的连续自然数段中的第一个数和最后一个数,

        两数之间用一个空格隔开,所有输出行的第一个按从小到大的升序排列,

        对于给定的输入数据,保证至少有一个解。

数据范围

        10 ≤ M ≤ 2, 000, 000,连续自然数段的长度至少为2.

例如输入:10000

       输出:18 142

                  297 328

                  388 412

                  1998 2002

双指针

如果用for(int i=0;i<m;i++)

                for(int j=i+1;j<m;j++)暴力方法

当x加到y恰好等于m时,我们要退出第二个循环

但是我们m=4000,如果sum再加上2000就超过了m,这个时候继续加下去没有意义。我们要停止第二个循环

并且让i加上1,那么问题又来了,我们又需要再次让sum从i+1开始遍历,显然暴力方法超时

显然会超时

我们借助双指针,当sum大于m的时候,我们让x指针右移,当sum小于m的时候,我们让y指针右移

#include <stdio.h>
int main()
{
	//设置两个指针x,y
	//一个指向左边,一个右边
	//sum值为x+(x+1)+(x+2)+……+(y-1)+(y)
	int m, x = 1, y = 2, sum = 3;//然后初始让sum值为x+y
		//m为0,1,2时候无连续自然数对
	scanf("%d", &m);
	while (y <= m / 2 + 1) {//结束条件是右指针到一半加1
	//eg.例如m是5时候,右边最多遍历到3,因为最少需要两个自然数
		if (sum < m) {//当小于时,就将右指针扩大
			y++;
			sum += y;
		}
		else if (sum == m) {//等于就输出,并且继续扩大右边
			printf("%d %d\n", x, y);
			y++;
			sum += y;
		}
		else {//大于就扩大左指针,将x去掉,然后x变为x+1
			sum -= x;
			x++;
		}
	}
	return 0;
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值