UVA / 山東科技大學OJ 3n+1problem
阿新 • • 發佈:2019-01-14
圖片是擷取的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了卻沒有超時,這是我始料未及的。
希望大家多多關注,小鑫會很努力地寫部落格的,我在這給各位大爺跪下了 噗通~~~~~~!