NKU两题简单题解析(递归分析与位运算技巧)
題目:http://acm.nankai.edu.cn/p1002.html
?
題意:對給定的f(n),當 n>=50025002 的時候,f(n)=n-5;當 n<50025002 的時候,f(n)=f(f(n+2005)),求f(n).
?
分析:注意本題給出數據n很大-2147483647<n<2147483647,如果你要遞歸,一是層數太多,會溢出,而是時間不是最優
的,那么在這里,雖然不能直接遞歸,但是我們還是可以用遞歸的思想。具體做法就是:
?
如果n>=50025002,那么我們可以直接計算,如果n<50025002,那么,我們可以先利用f(n)=f(f(n+2005))這個關系把f(n)的計算轉化到區間上去計算,那么我們可以這樣看:
?
?
其中這里k滿足條件:
?
這樣我們就可以直接計算,我們知道它等于n+2005k-5,那么現在n+2005k-5,就有兩種情況:
要么大于等于50025002,要么小于50025002,如果是大于等于,那么直接繼續計算,如果是小于,那么,就繼續轉換。
?
所以程序我們可以這樣寫:
?
void Solve(int n) {int k=1;while(k){if(n>=50025002){n-=5;k--;}else{n+=2005;k++;}}cout<<n<<endl; }
我感覺這樣很好理解,還可以進一步優化的,此處就省略了。
?
題目:http://acm.nankai.edu.cn/p1021.html
?
題意:所有3的冪的集合的子集中,輸出和為第k大的每個元素值。
?
分析:對于這個題呢,我感覺最好的做法就是用位運算,我們發現3的冪集合,比如:1,3,9,27,81,.....等等。
有一個特點,那么就是如果我們把輸入的k表示為二進制,比如5,就是101,注意二進制從由往左看的話,就代表1,9被選
了,而1+9=10恰好是第5大,所以這樣就很簡單了,程序可以這樣寫:
void Solve(LL n) {LL k=0;n--;while(n){if(n&1)cout<<(LL)pow(3.0,k*1.0)<<endl;n>>=1;k++;} }
?
總結
以上是生活随笔為你收集整理的NKU两题简单题解析(递归分析与位运算技巧)的全部內容,希望文章能夠幫你解決所遇到的問題。