1. 程式人生 > >UVA / 山東科技大學OJ 3n+1problem

UVA / 山東科技大學OJ 3n+1problem

圖片是擷取的OJ上的  就不復制文字啦;

二話不說,一貫風格先上程式碼

#include <stdio.h>
#include <string.h>
#define maxn 2000000
int s[maxn]={0};
int main()
{
    unsigned long long int a,b,j,i,n,max,c,m,x;
    while(scanf("%llu %llu",&a,&b)!=EOF)
    {
        int k=0;
        printf("%llu %llu",a,b);
        if(a>b) {m=a;a=b;b=m;}
        for(j=a,k=0;j<=b;j++,k++)
        {
            x=j;
            for(i=1;x!=1;i++)
            {
                if(x%2==0) x=x/2;
                else x=x*3+1;
            }
            s[k]=i;
        }
        max=0;
        for(m=0;m<=b-a;m++)
            if(s[m]>max) max=s[m];
        printf(" %d\n",max);
    }
    return 0;
}

這個程式碼還是能看出來我的一些毛病的,就比如說我特別害怕爆棧,所以資料型別開的比較大,希望大家能理解;

讓我們來解讀題目意思:

求每個數的最大週期長度,這個週期長度的定義在description裡面很明確就是這個數從一開始到變換到1的次數,一直迴圈直到這個數等於1。

for(i=1;x!=1;i++)
{
     if(x%2==0) x=x/2;
     else x=x*3+1;
}

 

迴圈這樣寫就可以了。但是數的週期長度要儲存下來這裡我就設定了一個s[ ]陣列,用來儲存兩個數之間的週期長度。
輸出要求是最大週期長度,所以我們用丁丁老師常說的打擂臺的方法來解決這類問題:定義max=0,將陣列中的元素一一作比,大數傳給max,最後輸出max就好啦。

這道題在VJ上UVA也有這道題  大概是最簡單的了,大家可以去試一試。

還有一種方法比較暴力但在處理多資料的情況下時間上會得到優化,但在處理大型別資料的情況下不知道會不會爆棧,反正在山東科技大學的OJ上是AC了的:

上程式碼:

#include <stdio.h>
#include <string.h>
#define maxn 2000000
int s[maxn]={0};
int main()
{
    unsigned long long int a,b,j,i,n,max,c,m;
    for(j=1;j<=1000000;j++)
    {
        a=j;
        for(i=1;a!=1;i++)
        {
            if(a<j) {i+=s[a]-1;break;}
            else if(a%2==0) a=a/2;
            else a=a*3+1;
        }
        s[j]=i;
    }
    while(scanf("%llu %llu",&a,&b)!=EOF)
    {
        printf("%llu %llu",a,b);
        if(a>b) {m=a;a=b;b=m;}
        max=0;
        for(;a<=b;a++)
        {
            if(s[a]>max) max=s[a];
        }
        printf(" %d\n",max);
    }
    return 0;
}

這個程式碼的意思很簡單,就是把1到1000000的所有數的週期長度都算出來儲存著,然後在比較,可以說是相當暴力了。

但是在SDUST OJ上AC了卻沒有超時,這是我始料未及的。

 

希望大家多多關注,小鑫會很努力地寫部落格的,我在這給各位大爺跪下了     噗通~~~~~~!