UVa11549:Calculator Conundrum

UVa11549:Calculator Conundrum

题目大意

有一个老旧的计算器只能显示前n个数字。现在给定一个数字k,每次给k平方,如果答案长度超过n则从最高位开始显示n个数字,丢弃其余数字。

要求:求出计算器能显示的最大数字。

Solution1(naive)

本题中得到的数列会出现循环,可以用一个set记录所有得到的数字,一旦出现重复数字停止循环,输出set中的最大值即可。

AC-Code(C++)

Time:540ms

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <string>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <cmath>
#include <climits>
#include <ctime>

using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
const int maxn = 30000 + 10;

/*
 * 刘汝佳 训练指南 P42
 */

int n,k,mask;

int getNext(int x){
    ll temp = (ll)x * x;
    while(temp >= mask)
        temp /= 10;
    return (int)temp;

}

int main(int argc, const char * argv[]) {

//    freopen("input.txt", "r", stdin);

    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d %d",&n,&k);
        mask = 1;
        for(int i=0;i<n;i++)
            mask *= 10;

        set<int> s;
        int ans = k;
        while(s.count(k)==0){
            s.insert(k);
            k = getNext(k);
            ans = max(ans,k);
        }

        printf("%d\n",ans);

    }

    return 0;
}

Solution2(floyd判圈法)

想象两个人赛跑,两人以不同的速度匀速运动。如果赛道是直线的,那么两个人以后再也不会相遇了,而如果两个人在一个环形赛道上跑步,那么速度快的那个人一定会在某一时刻从后面追上速度慢的那个人。

在这里循环的序列就是环形赛道,这种方法叫做floyd判圈法,这样做后因为不需要频繁的在set中查询元素是否存在,所以运行速度有了很大的提升,并且还将空间复杂度降为Ο(1)。

Note

在判圈的时候最开始我很顺的写出了如下代码,但这样会造成个别点没有取到就退出循环了,所以某些测试例子中的出的答案往往要比正确答案稍微小一点。

// wrong
do{
    k1 = getNext(k1);
    k2 = getNext(getNext(k2));
    ans = max(ans,max(k1,k2));
}while(k1 != k2);

AC-Code(C++)

Time:50ms

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <string>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <cmath>
#include <climits>
#include <ctime>

using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
const int maxn = 30000 + 10;

int n,k,mask;

/*
 * 刘汝佳 训练指南 P42
 */

int getNext(int x){
    ll temp = (ll)x * x;
    while(temp >= mask)
        temp /= 10;
    return (int)temp;

}

int main(int argc, const char * argv[]) {

//    freopen("input.txt", "r", stdin);

    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d %d",&n,&k);
        mask = 1;
        for(int i=0;i<n;i++)
            mask *= 10;

        int k1 = k;
        int k2 = k;
        int ans = k;
        // wrong
//        do{
//            k1 = getNext(k1);
//            k2 = getNext(getNext(k2));
//            ans = max(ans,max(k1,k2));
//        }while(k1 != k2);
        // right
        do{
            k1 = getNext(k1);
            k2 = getNext(k2);
            ans = max(ans,k2);
            k2 = getNext(k2);
            ans = max(ans,k2);
        }while(k1 != k2);

        printf("%d\n",ans);

    }

    return 0;
}

原文地址:https://www.cnblogs.com/irran/p/UVa11549.html

时间: 2024-10-07 09:42:05

UVa11549:Calculator Conundrum的相关文章

UVA11549 Calculator Conundrum 计算器谜题

就觉得这题的暴力解法时间复杂度应该会很高,可能循环节会比较小吧 比较好的收获就是这个Floyd判环法 #include <set> #include <cstdio> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; const int maxn = 100005; const int INF = 0x3f3f3f3f; LL pow10 (

[2016-03-19][UVA][11549][Calculator Conundrum]

时间:2016-03-19 21:27:43 星期六 题目编号:[2016-03-19][UVA][11549][Calculator Conundrum] 题目大意:给定数k每次取前n位不断平方,求出现的最大值是多少 方法: 方法1:模拟一遍过程,直到出现循环 方法2:Floyd判断算法,定义两个k,每次k1走一次,k2走两次,知道k1,k2相同 方法1:STL超级暴力方法 方法2:小小优化版 方法3:Floyd判圈算法 方法1:STL超级暴力方法 #include <set> #inclu

UVA之11549 - Calculator Conundrum

[题目] Problem C 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

Designing Efficient Algorithms [Examples]~C - 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 n most s

[UVa 11549]Calculator Conundrum

题解 显然按题意模拟会出现环,因为可能出现的数字数有限的,所以不可能无限的衍生下去. 那么我们就可以按题意模拟,遍历整个过程,统计最大值即可. 判环的环我们想到$hash$,也可以用$STL$中的$set$,但是复杂度高... $Floyd$判圈.一步两步法,有环的话肯定会相遇,空间复杂度可以降到$O(1)$,时间也快不少. 1 //It is made by Awson on 2017.9.18 2 #include <map> 3 #include <set> 4 #inclu

C - Calculator Conundrum

uva 11549 题意:你拥有一个老式计算机,它只能显示n为数字,有一天你输入数字k,接着一直平方下去,在这个过程中如果数字长度大于n,那么截取前n个数形成一个新的数k,再用这个新的数k一直平方下去,那么这个过程中能显示的最大数字是多少. 思路:在这个过程如果出现了以前出现过的数,那么从第一个开始到这个数就是一个循环节,后面的也与这个节一模一样,因为都是针对一个数字执行同一种操作. 为了时间复杂度上的考虑,可以使用set判重,耗时2.279s #include <iostream> #inc

UVA 11549 Calculator Conundrum Floyd判圈

题目链接:点击打开链接 题意: 输入n k,表示计算器能显示n位数字,初始有一个数字k 每次操作 k = k^2, 若超出n位则截取前n位. 求能获得的最大数字. 思路: 首先我们能判断这个操作一定存在循环. 那么如何终止循环,利用Floyd判圈法 让两个循环child1和child2刚开始都为k,然后child1每次变换一次,child2每次变换2次: 这样当child1再次等于child2时说明已经至少经过一个循环节了,因为child2已经从后面赶上child1了 import java.i

LeetCode OJ:Basic Calculator(基础计算器)

Implement a basic calculator to evaluate a simple expression string. The expression string may contain open ( and closing parentheses ), the plus + or minus sign -, non-negative integers and empty spaces . You may assume that the given expression is

[团队项目]----Math Calculator

团队项目 ----Math Calculator 任务: 1.每个团队从Github上fork这个项目的源代码 https://github.com/RABITBABY/We-have-bing 2.了解.部署.运行这个项目,理解其功能及实现: 3.进行必要的测试,发现软件的bug并记录,并进行bug的排除: 发布博客内容: 简要说明如何下载部署运行这个项目: 补充这个软件的单元测试并提交到Github上: 解释说明找出的bug及修复情况: 列出每个团队成员的个人贡献分. -----------