http://www.programming-challenges.com/pg.php?page=downloadproblem&probid=110101&format=html
UVA 100_The 3n+1 problem
题目大意:
从整数 n 开始,如果 n 是偶数,把它除以 2;如果 n 是奇数,把它乘 3 加 1。
用新得到的值重复上述步骤,直到 n = 1 时停止。
例如,n = 22 时该算法生成的序列是: 22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1
对于给定的 n,该序列的元素(包括 1)个数被称为 n 的循环节长度。
在上述例子中,22 的循环节长度为 16。输入两个数 i 和 j,
你的任务是计算 i 到 j(包含 i 和 j)之间的整数中,循环节长度的最大 值。
样例输入:
1 10 100 200 201 210 900 1000
样例输出:
1 10 20 100 200 125 201 210 89 900 1000 174
可以用暴力法,对每次输入的数值进行计算,求出最大值
#include<cstdio>
#include<iostream>
using namespace std;
int fun(int n)
{
int sum=1;
while(n!=1)
{
if(n&1)
n=n*3+1;
else
n>>=1;
sum++;
}
return sum;
}
int main()
{
int a,b,max,i,sum,t,x,y;
while(scanf("%d%d",&a,&b)!=EOF)
{
x=a;
y=b;
if(a>b)
{
t=a;
a=b;
b=t;
}
max=-1;
for(i=a;i<=b;i++)
{
sum=fun(i);
if(sum>max)
max=sum;
}
printf("%d %d %d\n",x,y,max);
}
return 0;
}
记录已计算的值,如果已经计算过,则直接读取
//因为计算过程中所得的数会超出int的范围,所以要用__int64或者long long型
#include<cstdio>
#include<iostream>
using namespace std;
#define N 1000000
long long num[N];
long long fun(long long n)
{
if(n==1)
return 1;
if(n&1)
n=n*3+1;
else
n>>=1;
if(n<N) //如果已经计算过,则不必再计算一次了,读取即可
{
if(!num[n])
{
num[n]=fun(n);
}
return 1+num[n];
}
return 1+fun(n);
}
int main()
{
long long a,b,t,x,y,max,temp;
while(scanf("%lld%lld",&a,&b)!=EOF)
{
x=a;
y=b;
if(x>y)
{
t=x;
x=y;
y=t;
}
max=-1;
for(t=x;t<=y;t++)
{
temp=fun(t);
if(max<temp)
max=temp;
}
printf("%lld %lld %lld\n",a,b,max);
}
return 0;
}