3n+1问题递归和非递归实现...

这是自己第一次独立完整的用递归解决问题,兴奋之余和大家分享。不仅解决3n+1,还能学习递归哦!

题目描述

该数链描述为:如果所给的数n是1,则数链长度为1,结束数链;如果是除1以外的奇数,则n=3*n+1,如果n是偶数,则n=n/2,并继续此过程。

输入

输入多组数据,每行两个数分别是i和j(0<i<=j<10000)。

输出

输出i到j区间中的(包括i和j)数链最长的长度,每行一个。

样例输入

1 10
100 200
201 210
900 1000

样例输出

20
125
89
174

递归版:

#include <stdio.h>

int cnt = 1;		  // 定义全局计数器

int sum(int n)
{
	if (1 == n)		  // 1直接退出, 递归边界
		return cnt;
	else if(n%2 == 1) // 奇数
	{
		sum(3*n + 1);
		cnt++;
	}
	else if (n%2 == 0) // 偶数
	{
		sum(n/2);
		cnt++;
	}
	return 0;
}

int main()
{
	int m, n;			// 区间
	int temp, temp1;	// 记录cnt变量的改变
	int i, max;			// i循环计数, max每一次比较的最大值
	
	printf("请输入两个数作为区间:");
	while (scanf("%d%d", &m, &n) != EOF)	// 输入区间[m,n]
	{
		max = -1;			// 初始化最大值为-1保证每一次都更新最大值,此处max<=0都满足
		if (m<=0 || m>=10000 || n<=0 || n>=10000)
			break;
		for (i = m; i <= n; i++)
		{ // 由于cnt是全局变量,所以需要用本次的值减去上一次的值,不太好理解
			temp = cnt;		// 记录上一次的cnt值
			sum(i);			// 调用递归
			temp1 = cnt - temp + 1;	// 由于cnt是全局变量,所以需要用本次的值减去上一次的值
			if (temp1 > max)
				max = temp1;
		}
		
		fprintf(stdout, "%d\n", max);
	}
}

当时递归一二十分钟就搞定了,关键卡在全局变量cnt的处理,小伙伴们仔细体会,应该还有更好的处理方式的

非递归版不想自己写了,贴上一个大家对比一下吧

非递归版:

#include "stdio.h"
void main()
{
	int i,j,k=1,n,flag=1,t,m=1,p;
	while (flag)
	{
		printf("请输入两个数:\n");
		scanf("%d %d",&i,&j);
		for (t=i;t<=j;t++) 
		{
			n=t;
			k=1;
			while (n!=1) 
			{
				if (n%2==0) 
				{
					n=n/2;
					k=k+1;
				}
				else
				{
					n=n*3+1;
					k=k+1;
				}
			}
			if (k>m) m=k;
		}
		printf("%d\n",m);
		scanf("%d",&p);
		switch(p) 
		{
		case 1: flag=1;
				break;
		case 0: flag=0;
		default:flag=0;
		}
		m=1;
	}
}

点赞