# 2020q3 Homework5 (quiz5) contributed by < `jonec76` > ###### tags: `sysprog-2020` > [作業說明](https://hackmd.io/@sysprog/r1z0WPWLD) > [題目](https://hackmd.io/@sysprog/2020-quiz5) ## 開發環境 ```shell $ uname -a Linux jonec76-Aspire-M7720 5.4.0-47-generic #51-Ubuntu SMP GNU/Linux ``` ## 參考解答 D1=2 D2=1 ZZZ=1-i ## Q1 - 解題想法 此題題目能夠處理浮點數的除法,在除法時又能夠分成兩種 case 探討,也就是除數是偶數或者奇數。 函式的第 1 個參數是被除數,型態可以是浮點數,第 2 個參數是除數。 ```c=1 int od = slots & 1; ``` 上方程式碼能夠檢查出現在的除數是否是奇數,並且進入下方的遞迴函式 ```c=1 divop(orig / 2, od ? (slots + 1) >> 1 : slots >> 1) ``` 先假設若除數在 `>>1` ( 除以 2 ) 的傳遞過程中,永遠都保持偶數的話,因為每次遞迴進去,`orig` 都會除以 2,所以這樣的結果,就是遞迴到終止條件的 `result`。那麽為何要額外處理奇數的? ```c=1 result += divop(result, slots); ``` 這邊能夠從下方的數學式子而來: $\dfrac{A}{B} = \dfrac{A}{B+1} + X,\ \ Where\ \ B\ \ is\ \ a\ \ odd\ \ number$ 接著移項: $X=\dfrac{A}{B}-\dfrac{A}{B+1}$ $\ \ \ \ =\dfrac{A}{B}*(B+1)$ $\ \ \ \ =\dfrac{A}{B+1} *\dfrac{1}{B}$ 在遞迴過程中,如果除數是奇數的話會讓該除數 + 1 之後往下傳,如同上方的 $A/(B+1) + X$,但因為原本是要計算 $A/(B)$,所以在往下遞迴時只做了加號左邊的部分,沒有算到 $X$。 所以在遞迴 backtracking 階段時,要將加號右邊的 $X$ 也加上才符合數學式子。而因為在前面已經算過 `result` 就是 $A/(B+1)$,要計算 $result*1/B$,只要再將這兩個值丟入 `divop` 進行計算即可。 ## Q3 - 解題想法 根據題目的數學式,以及看答案後才知背後意思。可以先看到下方數學式 $kx=N - \dfrac{(k-1)k}{2}$ 此題題目想要知道,$N$ 這個數可以被連續數相加的組合數有多少個,又知道上方的 x 一定是正整數,所以若可以找到一個 $k$ 是正整數且滿足上方的數學式,就可以得到一組 $k$ 個連續數相加的組合。 若假設由 3 個連續數組合出 $N$,那就可以知道 k=3,所以 $\dfrac{-(k-1)k}{2}=-3$ 當 $kx$ 計算出來之後,$x$ 是正整數的話就表示有解,也就是下方程式碼處理的部分 ```c=1 if (x % i == 0) ret++; ``` 那為什麼需要 `+=` 的運算呢? ```c=1 x += ZZZ; ``` 這部分在看完數學式才明白,這背後是梯形公式 $\dfrac{-(k-1)k}{2}=-1+-2+...+(-k+1)$ 展開後得到的結果,所以答案湊起來才是 `1 - i`