範例程式碼已於UVA
、瘋狂程設(CPE)
、ZeroJudge
上皆測試通過。
題意
給定一個正整數 n n n ,輸出一個最小的數字 $$ ,使得 q q q 的所有位數相乘等於 n n n 。
思路:貪婪(Greedy)
為使 q q q 的所有位數相乘等於 n n n ,需要對 n n n 做因數分解,並且只能使用 2 2 2 到 9 9 9 之中的數字。
由於 q q q 的位數越多,其數值越大,而我們希望 q q q 的位數越少越好,因此在因數分解時可以先使用較大的數字。舉個例子 8 = 2 3 8 = 2^3 8 = 2 3 ,但 8 < 222 8 < 222 8 < 222 。
同樣地,為使 q q q 的值最小,對於因數分解的結果,應該讓較小的數字放在前面,因此可以由小到大檢查因數分解的結果,並加入到答案中。
時間複雜度:O ( log n ) O(\log n) O ( log n ) ,因數分解。
空間複雜度:O ( 1 ) O(1) O ( 1 ) ,因數分解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 T = int (input ()) for _ in range (T): N = int (input ()) if N <= 1 : print (N) continue cnt = [0 ] * 10 for p in range (9 , 1 , -1 ): while (N % p == 0 ): cnt[p] += 1 N //= p if N != 1 : print (-1 ) else : ans = "" for p in range (2 , 10 ): ans += str (p) * cnt[p] print (ans)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #include <bits/stdc++.h> using namespace std;#define endl '\n' int main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); cout.tie (nullptr ); int t, n, cnt[10 ]; cin >> t; while (t--) { cin >> n; if (n <= 1 ) { cout << n << endl; continue ; } memset (cnt, 0 , sizeof (cnt)); for (int p = 9 ; p > 1 ; p--) { while (n % p == 0 ) { cnt[p]++; n /= p; } } if (n != 1 ) { cout << -1 << endl; } else { string ans = "" ; for (int p = 2 ; p < 10 ; p++) { while (cnt[p] --) { cout << p; } } cout << endl; } } return 0 ; }
寫在最後
Cover photo is remixed from @ccqxin , thanks for their work!