HDUOJ&&NYOJ----The 3n + 1 problem

這個題最初是在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;
}

 這個題之所以糾結這麼長時間就是因爲自己沒有認真的思考,一看題目很簡單,然後就去寫代碼,結果就是被耍的找不到北············以後不能大意,這個毛病很不好···



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章