每天一道算法题(12)——和为n的连续正数序列或者随机数

该博客介绍了如何找到所有和为给定正数n的连续正数序列。通过策略分析,当sum小于目标Sum时,右边界后移;等于Sum时,输出序列并后移右边界;当sum大于Sum时,左边界左移。此外,还探讨了特殊情况,如输入两个整数n和m,找出所有使和等于m的数列组合,采用递归方法分别考虑数是否参与查找的情况。
摘要由CSDN通过智能技术生成

        题目:输入一个正数n,输出所有和为n 连续正数序列。例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以输出3 个连续序列1-5、4-6 和7-8。


1.思路

       尊崇以下策略:

           (1)对于固定的left.当前sum值小于目标Sum,则right一直后移

           (2).sum==Sum。则输出序列,且将right后移

           (3)对于固定的right.,sum>Sum时,始终将left左移动


2.代码

void print(const int& left,const int& right){
	static int flag=0;//局部静态变量,仅仅初始化1次
	cout<<"NO:"<<++flag<<"--";
        for(int i=left;i<=right;i++)
		cout<<i<<" ";
	cout<<endl;
}

void findSequence(const int& Sum){
       int left=1,right=1,sum=1;
	   while(left<=Sum/2){
			if(sum==Sum){
			    print(left,right);
			    right++;
				sum+=right;
			}
			else if(sum>Sum){
				sum-=left;
				left++;
			}
			else{
				right++;
				sum+=right;
			}
	   }
}


     或者更加简短的,写作:

void findSequence(int Sum){
	int left=1,right=1,sum=1;
	while(left<=Sum/2){
		while(sum>Sum){
		    sum-=left;
		    left++;
		}
		if(sum==Sum)
			   print(left,right);
		right++;
		sum+=right;
	}
}

     即每一次大循环中都将right后移,在循环体内,若sum>Sum则将left左移动。相等时则输出。


3.特殊情况

        题目: 输入两个整数n和m,从数列1,2,3...n中随意取几个数,使其和等于m,要求列出所有的组合。

      分析。这里,从最大的数开始,对于每一个数,无非存在两种形式。即参与查找和不参与查找。使用递归即可。参与查找时,对应的n减小且和也减小。不参与查找时,只有n减小,和不变化。

#include <iostream>  
#include <list>  
using namespace std;  
list<int> list1;  
void find_factor(int sum,int n)  
{  
    //递归出口  
    if(n<=0||sum<0)  
        return;  
    //输出找到的数  
    if(sum==n)  
    {  
        list1.reverse();  
        for(list<int>::iterator iter=list1.begin();iter!=list1.end();iter++)  
            cout<<*iter<<"+";  
        cout<<n<<endl;  
        list1.reverse();  
    }  
    list1.push_front(n);  
    find_factor(sum-n,n-1);//n参与查找
    list1.pop_front();  
    find_factor(sum,n-1);//n不参与查找  
}  
  
int main(void)  
{  
    int sum,n;  
    cin>>sum>>n;  
    cout<<"所有可能的序列,如下:"<<endl;  
    find_factor(sum,n);  
    return 0;  
}  









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值