这个题最初是在HDUOJ上看到的,没费什么劲,直接水过。POJ也没费劲。后来发现学校OJ上也有这么一道题,就直接把昨晚写完的代码交上去。非常诡异的TLE了。唉,各种优化,各种纠结,C写完用C++写。结局还是TLE。后来想起来这个题要打表。可以省些时间。果然不出所料,嘿嘿,不过这期间也被坑了两次。一次运行出错,发现自己数组开的太小了,改成了题目中说的1000000.。兴冲冲的提交,刷新—>悲剧的TLE。后来一狠心直接开到10000;AC。唉····人生就这么纠结。
解题思路:这个题中告诉了判断的流程,如果输入的是一个偶数,除以2,奇数3N+1;不断循环,直到这个数最终化简为1(不必担心它化简不到)。题目中会给你两个数字n,m,你需要做的就是算出从小的数字到大的数字之间运行次数最多的次数。输出n,m,次数。 不过需要注意的是测试数据给的n,m不一定是n<m.故需要多加一层判断。
原题地址(只贴NYOJ的,其他的自己找找吧)点击打开链接。
代码如下:
C版:
#include<stdio.h>
#include<string.h>
int a[10003];
int main()
{
memset(a,0,sizeof(a));//数组清零
int i,j,max,n,m,k,l,count;
a[0]=0;a[1]=0;//避免出错,还是谨慎些好
for(i=2;i<=10000;i++)//打表
{
k=i;count=1;
while(k!=1)
{
if(k%2==1)k=3*k+1;
else k/=2;
count++;
}
a[i]=count;
}
while(scanf("%d %d",&n,&m)!=EOF)
{ max=0;
if(n>m)l=n,n=m,m=l;//判断两数大小
for(i=n;i<=m;i++)
{ if(a[i]>max)
max=a[i];
}
printf("%d %d %d\n",n,m,max);
}return 0;
}
C++版:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int d[10003];
int main()
{
int i,j,t,f;
memset(d,0,sizeof(d));
for(int k=2;k<10003;k++)//打表
{
t=k;
while(1!=t)
{
if(t&1)
{
t=t*3+1;
}
else t>>=1;
d[k]++;
}
}
while(cin>>i>>j)
{
int max=0,t=0;
cout<<i<<" "<<j<<" ";
if(i>j)
{
f=i;i=j;j=f;
}
for(int k=i;k<=j;k++)
{
if(max<d[k])
max=d[k];
}
cout<<max+1<<endl;
}
return 0;
}
这个题之所以纠结这么长时间就是因为自己没有认真的思考,一看题目很简单,然后就去写代码,结果就是被耍的找不到北············以后不能大意,这个毛病很不好···