zoukankan      html  css  js  c++  java
  • uva 11549 Calculator Conundrum

    https://vjudge.net/problem/UVA-11549

    题意:

    有一个老式计算器,只能显示n位数字。输入一个整数k,不断地平方,直到溢出。每次溢出的时候,会不断的显示最高n位和错误标记,之后错误标记会清除,继续平方。求在这个过程中出现的最大的数字。

    思路:

    首先,手算了几个例子,发现最后会产生循环,于是我就用map记录每个数字的出现,直到出现重复为止,然后输出map中的最大值。

    代码:

     1 #include <stdio.h>
     2 #include <map>
     3 using namespace std;
     4 typedef long long ll;
     5 map<ll,bool> mmp;
     6 
     7 ll mpow(int b,int n)
     8 {
     9     if (n == 0) return 1;
    10 
    11     long long ans = mpow(b, n / 2);
    12 
    13     ans *= ans;
    14 
    15     if (n & 1) ans *= b;
    16 
    17     return ans;
    18 }
    19 
    20 int cal(long long k)
    21 {
    22     int cnt = 0;
    23 
    24     while (k)
    25     {
    26         k /= 10;
    27         cnt++;
    28     }
    29 
    30     return cnt;
    31 }
    32 
    33 int main()
    34 {
    35     int t;
    36 
    37     scanf("%d",&t);
    38 
    39     while (t--)
    40     {
    41         mmp.clear();
    42 
    43         int n;
    44         long long k;
    45 
    46         scanf("%d%lld",&n,&k);
    47 
    48 
    49 
    50         long long m = mpow(10,n);
    51 
    52         if (k == 0)
    53         {
    54             printf("0
    ");
    55 
    56             continue;
    57         }
    58 
    59         if (k == 1)
    60         {
    61             printf("1
    ");
    62 
    63             continue;
    64         }
    65 
    66 
    67         while (1)
    68         {
    69             if (k == 1 || mmp[k]) break;
    70 
    71             mmp[k] = 1;
    72 
    73             k *= k;
    74 
    75             int cnt = cal(k);
    76 
    77             if (cnt <= n) continue;
    78 
    79             k /= mpow(10,cnt - n);
    80 
    81             //printf("%lld *
    ",k);
    82         }
    83 
    84         printf("%lld
    ",mmp.rbegin()->first);
    85     }
    86 
    87     return 0;
    88 }

    之后看到了lrjjj的做法,用了一个叫做floyd判圈法的方法,就是在一个环形跑道上,两个小孩子跑步,一个孩子的速度是另外一个的两倍,那么如果同时出发的话,快的孩子会超越慢的孩子,并在某一时刻两人会相遇。

    这题呢,就是一个循环,那么定义两个起始的数,一个每次变换一次,一个每次变换两次,那么两个数相等的时候就可以跳出循环,一个循环当中的所有数字肯定都遍历完了。这个方法主要是有着优秀的空间复杂度为O(1)。

    但是它的时间复杂度也比用map优秀:

    这是用floyd判圈法做的

    这是用map做的

    代码:

     1 #include <stdio.h>
     2 
     3 long long mpow(long long b,int n)
     4 {
     5     if (n == 0) return 1;
     6 
     7     long long ans = mpow(b,n / 2);
     8 
     9     ans *= ans;
    10 
    11     if (n & 1) ans *= b;
    12 
    13     return ans;
    14 }
    15 
    16 int cal(long long k)
    17 {
    18     int cnt = 0;
    19 
    20     while (k)
    21     {
    22         cnt++;
    23         k /= 10;
    24     }
    25 
    26     return cnt;
    27 }
    28 
    29 long long nex(long long k,int n)
    30 {
    31     k *= k;
    32 
    33     int cnt = cal(k);
    34 
    35     if (cnt <= n) return k;
    36 
    37     k = k / mpow(10,cnt - n);
    38 
    39     return k;
    40 }
    41 
    42 int main()
    43 {
    44     int t;
    45 
    46     scanf("%d",&t);
    47 
    48     while(t--)
    49     {
    50         int n;
    51         long long k;
    52 
    53 
    54         scanf("%d%lld",&n,&k);
    55 
    56         long long ans = k;
    57 
    58         long long k1 = k,k2 = k;
    59 
    60         do
    61         {
    62             k1 = nex(k1,n);if (k1 > ans) ans = k1;
    63             k2 = nex(k2,n);if (k2 > ans) ans = k2;
    64             k2 = nex(k2,n);if (k2 > ans) ans = k2;
    65 
    66         }while (k1 != k2);
    67 
    68         printf("%lld
    ",ans);
    69     }
    70 
    71     return 0;
    72 }
  • 相关阅读:
    【bzoj4987】Tree 树形dp
    【bzoj5093】 [Lydsy1711月赛]图的价值 组合数+斯特林数+NTT
    【BZOJ2159】Crash的文明世界 斯特林数+树形dp
    python enumerate函数同时遍历索引和函数
    gensim ——训练word2vec词向量的使用方法。
    moses工具的配置详解
    linux下boost库的安装
    python 调用word2vec
    python 默认编码
    GIZA++工具的使用介绍
  • 原文地址:https://www.cnblogs.com/kickit/p/7620215.html
Copyright © 2011-2022 走看看