题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1032
大意为执行如下操作:
1. 输入 n
2. 打印 n
3. 如果n==1则停止
4. 如果n为奇数则n=3*n+1;
5. 否则n=n/2;
6. 转到2;
给你一个数i,和j,问从i到j之间,打印次数最多的数的打印次数有多少次;
//
此题感觉没啥技巧,直接就是暴力模拟,如果f[i]存的是i的打印次数,只不过在找f[i]的时候把打印i必须打印的数字k的f[k]给找了出来,然后下次找的时候如果f[i]不为0,则直接给取,如果为0,则再找;
确定f[i]的值的时候可以用递归,顺便确定与之有关的数的值;
参考代码如下:
#include <iostream>
#include <cstring>
using namespace std;
int a[1000050];
int m,n;
int min(int i,int j)
{
if(i>j)
return j;
return i;
}
int get(__int64 t)
{
if(t==1)
return 1;
if(a[t])
return a[t];
if(t&1)
{
if(3*t+1<=1000040)
a[t]=get(3*t+1)+1;
else
{
__int64 k;
k=t;
while(k!=1)
{
a[t]++;
if(k&1)
k=k*3+1;
else
{
k=k/2;
if(k<=300000)
{
a[t]+=get(k);
break;
}
}
}
}
}
else
a[t]=get(t/2)+1;
return a[t];
}
void execute()
{
int a1,a2;
a1=min(m,n);
a2=m+n-a1;
int res=0;
int i,t;
t=0;
for(i=a1;i<=a2;i++)
{
a[i]=get(i);
if(a[i]>res)
res=a[i];
}
cout<<n<<' '<<m<<' '<<res<<endl;
}
int main()
{
memset(a,0,sizeof(a));
a[1]=1;
int i;
int len=1;
for(i=1;i<=1000040;i*=2,len++)
{
a[i]=len;
}
while(cin>>n>>m)
execute();
return 0;
}