mymilkbottles

越努力,越幸运! 以现在大多数人的努力程度之低,根本轮不到可以拼天赋。...

UVA - 11549 Calculator Conundrum (循环节)(Floyd判圈算法,快慢指针)

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 over ows. When the result
over ows, only the
n
most signi cant digits are displayed on the screen and an error ag 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?”
Input
The rst line of the input contains an integer
t
(1

t

200), the number of test cases. Each test case
contains two integers
n
(1

n

9) and
k
(0

k<
10
n
) where
n
is the number of digits this calculator
can display
k
is the starting number.
Output
For each test case, print the maximum number that Alice can get by repeatedly squaring the starting
number as described.
SampleInput
2
1 6
2 99
SampleOutput
9
99

题解:
一般对于这种无限循环的东西来说,都是有规律可循的,比如这道题就是循环节的运用,不断的平方取前n个数字,然后判断是否出现过就行了。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#include<set>
#include<cmath>

set<int> S;

int main(){
    int T,n,k;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&k,&n);
        int ans=n;
        S.clear();
        int now=n;
        long long t;
        while(true){
            t=(long long)now*now;
            int sum=0;
            int digit=(int)log10(t)+1;
            if(digit>k){
                for(int i=0;i<digit-k;++i){
                    t/=10;
                }
            }
            if(S.find((int)t)!=S.end())break;
            ans=max(ans,(int)t);
            S.insert(t);
            now=t;
        }
        printf("%d\n",ans);
    }
    return 0;
}

这里使用了set,不仅仅空间上消耗很大,时间上也并不是最优的。
这道题最好的方法是使用Floyd判圈算法来解决环的问题,Floyd判圈算法是通过快慢指针来实现的。

#include<cstdio>
#include<cmath>
#include<iostream>
using namespace std;

int Next(int now,int k){
    long long t=(long long)now*now;
    int digit=(int)log10(t*1.00)+1;
    if(digit>k){
        for(int i=0;i<digit-k;++i)t/=10;
    }
    return (int)t;
}

int main() {
    int T,n,k;
    scanf("%d",&T);
    while(T--) {
        scanf("%d%d",&n,&k);
        int ans=k;
        int slow=k,fast=Next(k,n);
        while(slow^fast) {
            slow=Next(slow,n);
            if(fast>ans)ans=fast;
            fast=Next(fast,n);
            if(fast>ans)ans=fast;
            fast=Next(fast,n);
        }
        printf("%d\n",ans);
    }
    return 0;
}
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mymilkbottles/article/details/52383824
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

UVA - 11549 Calculator Conundrum (循环节)(Floyd判圈算法,快慢指针)

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭