zoukankan      html  css  js  c++  java
  • UVA 11549 CALCULATOR CONUNDRUM(Floyd判圈算法)

    CALCULATOR CONUNDRUM
     

     

    Alice got a hold of an old calculator that can display n digits. She was bored enough to come up with the following time waster.

    She enters a number k then repeatedly squares it until the result overflows. When the result overflows, only the most significant digits are displayed on the screen and an error flag appears. Alice can clear the error and continue squaring the displayed number. She got bored by this soon enough, but wondered:

    “Given n and k, what is the largest number I can get by wasting time in this manner?”

    Program Input

    The first line of the input contains an integer (1 ≤ ≤ 200), the number of test cases. Each test case contains two integers (1 ≤ ≤ 9) and (0 ≤ < 10n) where n is the number of digits this calculator can display is the starting number.

    Program Output

    For each test case, print the maximum number that Alice can get by repeatedly squaring the starting number as described.

    Sample Input & Output

    INPUT

    2
    1 6
    2 99
    

    OUTPUT

    9
    99

    题目大意:计算器谜题。有一个老式计算器,只能显示n位数字。有一天,你无聊了,于是输入一个整数k,然后反复平方,直到溢出。每次溢出时,计算器会显示出结果的最高n位和一个错误标记。然后清除错误标记,继续平方。如果一直这样做下去,能得到的最大数是多少?比如,当n=1,k=6时,计算器将以此显示6、3(36的最高位),9、8(81的最高位),6(64的最高位),3...

    分析:题目已经暗示了计算器显示出的数将出现循环。
      想象一下,假设两个小孩在一个“可以无限向前跑”的跑道上赛跑,同时出发,但其中一个小孩的速度是另一个的2倍。如果跑道是直的,跑得快的小孩永远在前面;但如果跑道有环,则跑得快的小孩将“追上”跑得慢的小孩。
      这个算法称为Floyd判圈算法,不仅空间复杂度降为O(1),运行时间也将缩短到0.5秒。

    代码如下:
     1 #include<iostream>
     2 using namespace std;
     3 
     4 int buf[10];
     5 
     6 int next(int n, int k) {
     7   if(!k) return 0;
     8   long long k2 = (long long)k * k;
     9   int L = 0;
    10   while(k2 > 0) { buf[L++] = k2 % 10; k2 /= 10; } // 分离并保存k2的各个数字
    11   if(n > L) n = L;
    12   int ans = 0;
    13   for(int i = 0; i < n; i++) // 把前min{n,L}位重新组合
    14     ans = ans * 10 + buf[--L];
    15   return ans;
    16 }
    17 
    18 int main() {
    19   int T;
    20   cin >> T;
    21   while(T--) {
    22     int n, k;
    23     cin >> n >> k;
    24     int ans = k;
    25     int k1 = k, k2 = k;
    26     do {
    27       k1 = next(n, k1); // 小孩1
    28       k2 = next(n, k2); if(k2 > ans) ans = k2; // 小孩2,第一步
    29       k2 = next(n, k2); if(k2 > ans) ans = k2; // 小孩2,第二步
    30     } while(k1 != k2); // 追上以后才停止
    31     cout << ans << endl;
    32   }
    33   return 0;
    34 }
     
  • 相关阅读:
    右键点击任务栏程序没有锁定菜单
    CMD命令:不是内部或者外部命令也不是可运行的程序或批处理文件
    通道闸机
    Activex、OLE、COM、OCX、DLL之间区别、联系[转]
    C#图像显示实现拖拽、锚点缩放功能【转】
    顶级人生规划[转]
    jqGrid选择列控件向右拖拽超出边界处理
    强力推荐!那些你不能错过的 GitHub 插件和工具
    GitHub 托管的10款免费开源 windows 工具
    实现阶层跨越的捷径
  • 原文地址:https://www.cnblogs.com/acm-bingzi/p/3202896.html
Copyright © 2011-2022 走看看