前同事的同事去某間公司被問的題目。
題目 Link to heading
給定正整數 $n$,找出位數總和與它相同,而且大於它的最小正整數。例如
- 772 => 781
- 293 => 329
- 100 => 10000
解法 Link to heading
初始作法 Link to heading
- 對於末兩位數字小於 90,且非 10 的倍數的數字,
+9
就結束。 - 剩下的數字,我是先推出至少要加幾個 9,搭配
+9
迴圈檢查 digit sum 是否相同。
改善解法 Link to heading
做出來之後,我測試了一下剩餘的例子,發現有規律性,所以改成以下寫法。但沒有也沒空證明是對的 😆
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
data := 998
ans := getAns(data)
elapsed := time.Since(t)
fmt.Printf("Elapsed time: %v, data = %d, ans = %d", elapsed, data, ans)
}
func getAns(data int) int {
r := data % 100
q := data / 100
step := 0
if r == 0 {
b0 := 100
for q%10 == 0 {
b0 *= 10
q /= 10
}
s0 := q % 10
step = (b0-1)*(10-s0)/9 + 1
q /= 10
for q%10 == 9 {
step += s0
s0 *= 10
q /= 10
}
} else if r > 90 {
b9X := 10
s9X := r % 10
for q%10 == 9 {
b9X *= 10
q /= 10
}
step = (b9X-1)*s9X/9 + 1
} else if r%10 == 0 {
sX0 := r / 10
step = 11 - sX0
for q%10 == 9 {
step += sX0
sX0 *= 10
q /= 10
}
} else {
step = 1
}
return data + step*9
}
結論 Link to heading
不知道我前同事的同事是在什麼情況下被問。如果是白板題,我差不多就用初始解法打發,因為我數學不好也缺乏敏銳度。如果是考線上我才會用觀察法重新改寫。