uva 11549

/**
 * @brief uva 11549
 * @file 11549.cpp
 * @author mianma
 * @created 2014/12/31 11:43
 * @edited  2014/12/31 11:43
 * @type 
 * @note floyd判圈算法
 */
#include <fstream>
#include <iostream>
#include <cstring>
#include <cmath>

using namespace std;

#define max(a, b)  ((a) > (b) ? (a) : (b))
#define min(a, b)  ((a) > (b) ? (b) : (a)) 
#define abs(a)     ((a) >  0  ? (a) : (0 - (a)))
#define CLR(vec)   memset(vec, 0, sizeof(vec))

#ifdef DEBUG
ifstream in;
ofstream out;
#define CIN in
#define COUT out
#else
#define CIN cin
#define COUT cout
#endif

#define MAXB 25

typedef long long int ll;

int t, n;
ll k;

ll next(int n, ll num){
    static int buf[MAXB];
    ll tmp = num*num;
    int cnt = 0;
    while(tmp != 0){
        buf[cnt++] = tmp%10;
        tmp /= 10;
    }
    n = min(n, cnt);
    ll ans = 0;
    for(int i = 0; i < n; i++)
        ans = ans*10 + buf[--cnt];
    return ans;
}

int solve(int n, ll k){
    ll t1, t2, ans;
    t1 = t2 = ans = k;
    do{
        t1 = next(n, t1);
        t2 = next(n, t2);
        ans = max(t2, ans);
        t2 = next(n, t2);
        ans = max(t2, ans);
    }while(t1 != t2);
    return ans;
}

int main(void){
    ios_base::sync_with_stdio(0);
#ifdef DEBUG
    CIN.open("./in",  ios::in);
    COUT.open("./out",  ios::out);
#endif
    CIN >> t;
    for(int cases = 1; cases <= t; cases++){
        CIN >> n >> k;
        COUT << solve(n, k) << "\n";
    }
    return 0;
}
时间: 2024-10-17 14:54:48

uva 11549的相关文章

[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

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

uva 11549计算器谜题(floyd判圈算法)

 题意:有个老式计算器,每次只能记住一个数字的前n位.现在输入一个整数k,然后反复平方,一直做下去,能得到的最大数是多少.例如,n=1,k=6,那么一次显示:6,3,9,1... 思路:这个题一定会出现循环,所以一个个模拟,遇到相同的就再之前所有数中找最大的输出即可. 最容易想到的就是set判重,一开始k直接生算每次除十......超时 然后看了书,用string,ac,很方便但是时间达到了4s,果然string和stringstream好慢啊......... 又改成了记录k*k的每一位,

UVa 11549 计算器谜题(Floyd判圈算法)

https://vjudge.net/problem/UVA-11549 题意: 有一个老式计算器,只能显示n位数字,输入一个整数k,然后反复平方,如果溢出的话,计算器会显示结果的最高n位.如果一直这样做下去,能得到的最大数是多少? 思路: 这个肯定是会循环的. 比较普通的做法就是用set来判断是否出现过来终止循环. 另一个高效算法:Floyd判圈算法!! 想象一下,假设有两个小孩子在一个“可以无限向前跑”的跑道上赛跑,同时出发,但其中一个孩子的速度是另一个两倍.如果跑到是直的,跑得快的小孩永远

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

C - Calculator Conundrum

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

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

UVA 562 Dividing coins --01背包的变形

01背包的变形. 先算出硬币面值的总和,然后此题变成求背包容量为V=sum/2时,能装的最多的硬币,然后将剩余的面值和它相减取一个绝对值就是最小的差值. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 50007 int c[102],d

UVA 10341 Solve It

Problem F Solve It Input: standard input Output: standard output Time Limit: 1 second Memory Limit: 32 MB Solve the equation: p*e-x + q*sin(x) + r*cos(x) + s*tan(x) + t*x2 + u = 0 where 0 <= x <= 1. Input Input consists of multiple test cases and te