http://www.programming-challenges.com/pg.php?page=downloadproblem&probid=110101&format=html

UVA 100_The 3n+1 problem

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=29&page=show_problem&problem=36

题目大意:

从整数 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;
}



posted on 2012-02-28 15:58  pcoda  阅读(203)  评论(0编辑  收藏  举报