1. 程式人生 > >11549 Calculator Conundrum (迴圈節)(Floyd判圈演算法,快慢指標)

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;
}