zoukankan      html  css  js  c++  java
  • Codeforces Round #491 (Div. 2) F. Concise and clear

    F. Concise and clear
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    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 106106, instead of 1000000000  —109109, instead of 1000000007 — 109+7109+7.

    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.

    Input

    The only line contains a single integer nn (1n100000000001≤n≤10000000000).

    Output

    Output a concise notation of the number nn. If there are several concise notations, output any of them.

    Examples
    input
    Copy
    2018
    output
    Copy
    2018
    input
    Copy
    1000000007
    output
    Copy
    10^9+7
    input
    Copy
    10000000000
    output
    Copy
    100^5
    input
    Copy
    2000000000
    output
    Copy
    2*10^9
    Note

    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);
     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
  • 相关阅读:
    Java基础知识强化94:Calendar类之Calendar概述和获取日历字段的方法
    Java基础知识强化93:算一下你来到这个世界多少天的案例
    Java基础知识强化92:日期工具类的编写和测试案例
    Java基础知识强化91:DateFormat类之DateFormat实现日期和字符串的相互转换
    Java基础知识强化90:Date类之Data类中日期和毫秒相互转换
    Java基础知识强化89:Date类之Data类概述及其方法
    Java基础知识强化88:BigDecimal类之BigDecimal类引入和概述 以及 BigDecimal的使用(加减乘除)
    Java基础知识强化87:BigInteger类之BigInteger加减乘除法的使用
    Java基础知识强化86:BigInteger类之BigInteger概述和构造方法
    Java基础知识强化85:System类之arraycopy()方法(数组拷贝)
  • 原文地址:https://www.cnblogs.com/BIGTOM/p/9220425.html
Copyright © 2011-2022 走看看