標籤:
【問題描述】
已知m、n為整數,且滿足下列兩個條件:
① m、n∈{1,2,…,k},即1≤m,n≤k,(1≤k≤109)。
②(n2-m*n-m2)2=1
你的任務是:編程輸入正整數k,求一組滿足上述兩個條件的m、n,並且使m2+n2的值最大。例如,從鍵盤輸入k=1995,則輸出:m=987 n=1597。
【輸入範例】
1995
【輸出範例】
m=987
n=1597
代碼如下:
1 long m,n,k; 2 double delt1,delt2,n1,n2; 3 scanf("%d",&k); 4 for(m=k;m>=1;m--) 5 { 6 delt1=sqrt(5*m*m+4); 7 n1=(m+delt1)/2; 8 n=n1; 9 if(n==n1&&n<=k) break;10 11 delt2=sqrt(5*m*m-4);12 n2=(m+delt2)/2;13 n=n2;14 if(n==n2&&n<=k) break;15 }16 printf("m=%d\nn=%d\n",m,n);View Code
批註:該演算法確實挺好,簡潔、高效率,但是有一個問題比較明顯,那就是當k的值達到10^9時,for迴圈內,m從k開始向1遍曆。當m的值取10^9時,計算delt的時候,m^2會溢出。而且並非只有當k達到10^9才會有這個問題,當k達到10^5時就會出現這個問題。想要自己寫一個函數去實現高精度數的開平方根,似乎也不是這麼容易。所以,可以看看下面的遞推演算法。
標準答案是:
代碼如下:
1 int n=1,m=1,k,t; 2 cin>>k; 3 do 4 { 5 t=n+m; 6 if(t<=k) 7 { 8 m=n; 9 n=t;10 }11 }12 while(t<=k);13 cout<<"m="<<m<<endl<<"n="<<n;View Code
批註:一開始閱讀該演算法,實在無法理解為何會是跟斐波那契數列一樣的規律。後來查資料,閱讀理解,終於看懂。下面做一個記錄。
極值問題(acms)