Codeforces Round #491 (Div. 2) F. Concise and clear
Vasya is a regular participant at programming contests and is already experienced in finding important sentences in long statements. Of course, numbers constraints are important — factorization of a number less than 1000000 is easier than of a number less than 1000000000. However, sometimes it‘s hard to understand the number at the first glance. Could it be shortened? For example, instead of 1000000 you could write
Vasya decided that, to be concise, the notation should follow several rules:
- the notation should only consist of numbers, operations of addition ("+"), multiplication ("*") and exponentiation ("^"), in particular, the use of braces is forbidden;
- the use of several exponentiation operations in a row is forbidden, for example, writing "2^3^4" is unacceptable;
- the value of the resulting expression equals to the initial number;
- the notation should consist of the minimal amount of symbols.
Given nn, find the equivalent concise notation for it.
InputThe only line contains a single integer nn (1≤n≤100000000001≤n≤10000000000).
OutputOutput a concise notation of the number
2018output Copy
2018input Copy
1000000007output Copy
10^9+7input Copy
10000000000output Copy
100^5input Copy
2000000000output Copy
2*10^9Note
The third sample allows the answer 10^10 also of the length 55.
思路:10^10特判一下,之後剩的位數不超過10位,這樣通過改字符來縮減長度最多出現4個字符,又單獨的乘法和加法不會縮減長度,所以一定有^,於是我們將n表示成a^b*c+d的形式,a從2枚舉到sqrt(n),b從2枚舉到loga(n),貪心找最大的c,然後唯一確定一個d,這樣就得到了一個sqrt(n)*log(n)復雜度的假算法,會WA9。此算法假在c或d也可能表示成e^f的形式,於是我們通過一個map預處理出所有能表示成這個形式的數,查詢的時候和map裏的比一下取長度最短就行了。預處理和枚舉復雜度都為O(sqrt(n)*log2(n))。
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 36 /* 37 #include <ext/pb_ds/assoc_container.hpp> 38 #include <ext/pb_ds/tree_policy.hpp> 39 40 using namespace __gnu_pbds; 41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T; 42 */ 43 44 ll n; 45 string ans; 46 void add(string &S, ll t) { 47 char s[29]; 48 int l = 0; 49 while (t) { 50 s[++l] = t % 10; 51 t /= 10; 52 } 53 while (l) { 54 S += s[l] + ‘0‘; 55 --l; 56 } 57 } 58 map<ll, string> mmp; 59 void pre() { 60 for (ll a = 2; a <= sqrt(n + 0.5); ++a) { 61 ll tt = a; 62 for (int b = 2; ; ++b) { 63 tt *= a; 64 if (tt > n) break; 65 string t2 = ""; 66 add(t2, a); 67 t2 += "^"; 68 add(t2, b); 69 if (mmp.count(tt)) { 70 string t1 = mmp[tt]; 71 if (t2.length() < t1.length()) { 72 mmp[tt] = t2; 73 } 74 } else { 75 mmp[tt] = t2; 76 } 77 } 78 } 79 } 80 int main() { 81 scanf("%lld", &n); 82 if (n < 1000) { 83 printf("%lld\n", n); 84 } else { 85 pre(); 86 add(ans, n); 87 for (ll a = 2; a <= sqrt(n + 0.5); ++a) { 88 ll tt = a; 89 for (ll b = 2; ; ++b) { 90 tt *= a; 91 if (tt > n) break; 92 string res = ""; 93 add(res, a); 94 res += "^"; 95 add(res, b); 96 ll c = n / tt; 97 for (ll tc = c; tc >= max(1ll, c - 0); --tc) { 98 ll d = n - tt * tc; 99 string res2 = res; 100 if (1 != tc) { 101 res2 += "*"; 102 string res4 = ""; 103 add(res4, tc); 104 if (mmp.count(tc)) { 105 if (res4.length() < mmp[tc].length()) { 106 res2 += res4; 107 } else { 108 res2 += mmp[tc]; 109 } 110 } else { 111 res2 += res4; 112 } 113 } 114 if (d) { 115 res2 += "+"; 116 string res3 = ""; 117 add(res3, d); 118 if (mmp.count(d)) { 119 if (res3.length() < mmp[d].length()) { 120 res2 += res3; 121 } else { 122 res2 += mmp[d]; 123 } 124 } else { 125 res2 += res3; 126 } 127 } 128 if (res2.length() < ans.length()) { 129 ans = res2; 130 } 131 } 132 } 133 } 134 cout << ans << endl; 135 } 136 return 0; 137 }View Code
Codeforces Round #491 (Div. 2) F. Concise and clear