#include <cstdio>
#include <vector>
const int MAX_K = 1000000; // 1 mln
std::vector<int> unary;
std::vector<int> track;
void init() {
std::vector<bool> primes;
unary.resize(MAX_K + 1);
primes.resize(MAX_K + 1, true);
track.resize(MAX_K + 1);
primes[0] = primes[1] = false;
for(int i = 0; i <= MAX_K; ++i) {
unary[i] = i;
track[i] = i - 1;
}
int upto = MAX_K / 2;
for(int p = 3; p <= upto; ++p) {
if(unary[p - 1] + 1 < unary[p]) {
unary[p] = unary[p - 1] + 1;
track[p] = p - 1;
}
// TODO: can be skipped?
if(!primes[p]) {
continue;
}
for(int k = 2; k <= p; k++) {
int i = k * p;
if(i > MAX_K) {
break;
}
if(unary[k] + unary[p] < unary[i]) {
unary[i] = unary[p] + unary[k];
track[i] = p;
}
primes[i] = false;
}
}
for(int p = upto + 1; p <= MAX_K; ++p) {
if(unary[p - 1] + 1 < unary[p]) {
unary[p] = unary[p - 1] + 1;
track[p] = p - 1;
}
}
}
void print_expr(int k) {
if(k == 1) {
printf("1");
return;
}
int from = track[k];
if(k - from == 1) {
printf("(1+");
print_expr(from);
printf(")");
}
else {
printf("(");
print_expr(from);
printf("*");
print_expr(k / from);
printf(")");
}
}
void solve(int k) {
if(k <= MAX_K) {
print_expr(k);
}
else {
int fact = k / 1000;
print_expr(fact);
printf("*");
print_expr(1000);
int rest = k - 1000 * fact;
if(rest > 0) {
printf("+");
print_expr(rest);
}
}
printf("\n");
}
int main() {
int t, k;
init();
scanf("%d", &t);
while(t--) {
scanf("%d", &k);
solve(k);
}
}
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 | #include <cstdio> #include <vector> const int MAX_K = 1000000; // 1 mln std::vector<int> unary; std::vector<int> track; void init() { std::vector<bool> primes; unary.resize(MAX_K + 1); primes.resize(MAX_K + 1, true); track.resize(MAX_K + 1); primes[0] = primes[1] = false; for(int i = 0; i <= MAX_K; ++i) { unary[i] = i; track[i] = i - 1; } int upto = MAX_K / 2; for(int p = 3; p <= upto; ++p) { if(unary[p - 1] + 1 < unary[p]) { unary[p] = unary[p - 1] + 1; track[p] = p - 1; } // TODO: can be skipped? if(!primes[p]) { continue; } for(int k = 2; k <= p; k++) { int i = k * p; if(i > MAX_K) { break; } if(unary[k] + unary[p] < unary[i]) { unary[i] = unary[p] + unary[k]; track[i] = p; } primes[i] = false; } } for(int p = upto + 1; p <= MAX_K; ++p) { if(unary[p - 1] + 1 < unary[p]) { unary[p] = unary[p - 1] + 1; track[p] = p - 1; } } } void print_expr(int k) { if(k == 1) { printf("1"); return; } int from = track[k]; if(k - from == 1) { printf("(1+"); print_expr(from); printf(")"); } else { printf("("); print_expr(from); printf("*"); print_expr(k / from); printf(")"); } } void solve(int k) { if(k <= MAX_K) { print_expr(k); } else { int fact = k / 1000; print_expr(fact); printf("*"); print_expr(1000); int rest = k - 1000 * fact; if(rest > 0) { printf("+"); print_expr(rest); } } printf("\n"); } int main() { int t, k; init(); scanf("%d", &t); while(t--) { scanf("%d", &k); solve(k); } } |
English