#include <iostream> #include <sstream> #include <vector> #include <unordered_map> struct Result { std::string s; long num; }; std::string makeSumOfOnes(long k) { if (k <= 0) return std::string(); std::stringstream ss; ss << "1"; for (long i = 1; i<k; ++i) { ss << "+1"; } return ss.str(); } Result getAnswer(long k, const std::vector<long>& primes, std::unordered_map<long, Result>& results) { if (results.find(k) != results.end()) { return results[k]; } Result minResult; minResult.num = 101; if (k == 0) { minResult.num = 0; results[k] = minResult; return minResult; } if (k <= 5) { minResult.s = makeSumOfOnes(k); minResult.num = k; results[k] = minResult; return minResult; } for (auto& prime : primes) { if (prime >= k) break; auto res1 = getAnswer(prime, primes, results); if (res1.num > prime) { res1.num = prime; res1.s = makeSumOfOnes(prime); } if (res1.num > 100) continue; long d = k / prime; auto res2 = getAnswer(d, primes, results); if (res2.num > d) { res2.num = d; res2.s = makeSumOfOnes(d); } if (res2.num >100) continue; long rest = k - d*prime; auto res3 = getAnswer(rest, primes, results); if (res3.num > rest) { res3.num = rest; res3.s = makeSumOfOnes(rest); } if (res3.num >100) continue; long newSum = res1.num + res2.num + res3.num; if (newSum < minResult.num) { minResult.num = newSum; std::stringstream ss; ss << "(" << res1.s << ")*(" << res2.s << ")"; if (!res3.s.empty()) { if (res3.s.size() > 1) ss << "+(" << res3.s << ")"; else ss << "+" << res3.s; } minResult.s = ss.str(); } } results[k] = minResult; return minResult; } int main() { std::ios::sync_with_stdio(false); const std::vector<long> primes = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 }; std::unordered_map<long, Result> results; long t; std::cin >> t; for (int i = 0; i<t; ++i) { long k; std::cin >> k; Result res = getAnswer(k, primes, results); if (res.num < 101) { std::cout << res.s << std::endl; } else { std::cout << "NIE" << std::endl; } } return 0; }
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | #include <iostream> #include <sstream> #include <vector> #include <unordered_map> struct Result { std::string s; long num; }; std::string makeSumOfOnes(long k) { if (k <= 0) return std::string(); std::stringstream ss; ss << "1"; for (long i = 1; i<k; ++i) { ss << "+1"; } return ss.str(); } Result getAnswer(long k, const std::vector<long>& primes, std::unordered_map<long, Result>& results) { if (results.find(k) != results.end()) { return results[k]; } Result minResult; minResult.num = 101; if (k == 0) { minResult.num = 0; results[k] = minResult; return minResult; } if (k <= 5) { minResult.s = makeSumOfOnes(k); minResult.num = k; results[k] = minResult; return minResult; } for (auto& prime : primes) { if (prime >= k) break; auto res1 = getAnswer(prime, primes, results); if (res1.num > prime) { res1.num = prime; res1.s = makeSumOfOnes(prime); } if (res1.num > 100) continue; long d = k / prime; auto res2 = getAnswer(d, primes, results); if (res2.num > d) { res2.num = d; res2.s = makeSumOfOnes(d); } if (res2.num >100) continue; long rest = k - d*prime; auto res3 = getAnswer(rest, primes, results); if (res3.num > rest) { res3.num = rest; res3.s = makeSumOfOnes(rest); } if (res3.num >100) continue; long newSum = res1.num + res2.num + res3.num; if (newSum < minResult.num) { minResult.num = newSum; std::stringstream ss; ss << "(" << res1.s << ")*(" << res2.s << ")"; if (!res3.s.empty()) { if (res3.s.size() > 1) ss << "+(" << res3.s << ")"; else ss << "+" << res3.s; } minResult.s = ss.str(); } } results[k] = minResult; return minResult; } int main() { std::ios::sync_with_stdio(false); const std::vector<long> primes = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 }; std::unordered_map<long, Result> results; long t; std::cin >> t; for (int i = 0; i<t; ++i) { long k; std::cin >> k; Result res = getAnswer(k, primes, results); if (res.num < 101) { std::cout << res.s << std::endl; } else { std::cout << "NIE" << std::endl; } } return 0; } |