【省选模拟试题】计算器谜题

【问题描述】

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

【输入格式】

  输入的第一行为一个整数T(1≤T≤200),即测试数据的数量。以下T行,每行包含两个整数n和k(1≤n≤9,0≤k<10^n)。

【输出格式】

  对于每组数据,输出你能得到的最大数。

【输入样例】

2
1 6
2 99

【输出样例】

9
99

真的是谜一般的一道题。
因为题目没有说要循环多少次,可以知道得出的数一定是会出现循环的(不然一直找下去肯定会超时)。一旦出现已经出现过的数,说明循环出现。
可以用set或map判断,但更好的是用Floyd判圈法判定:

爸爸和孩子在一个跑道上跑步,爸爸的速度是孩子的两倍,同时出发,如果跑道是直的爸爸会一直在孩子前面,边跑边回头逗孩子,若跑道是环形的,爸爸将会追上孩子,孩子跑了半圈,爸爸跑了一圈,孩子跑一圈,爸爸跑两圈,此时父子两相遇了。
这道题目简单来说就是求某一个循环里的最大值,而floyd判圈算法,爸爸路程最少是完全遍历了一个某循环。
int k1=k,k2=k; 
        ans=k;
        do
        {
            task(n,k1,k1);
            task(n,k2,k2); ans=max(ans,k2);
            task(n,k2,k2); ans=max(ans,k2);
        }while(k1!=k2);

【数据范围】

1≤T≤200
1≤n≤9,0≤k<10^n

#include<cstdio>
#include<algorithm> 
using namespace std;  
int t,n,k,ans,a[150];
int d[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};

void read(int &x)
{
    x=0;
    bool ok=0;
    char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    while((ch>='0'&&ch<='9')||ch=='-')
    {
        if(ch=='-') ok=1;
        else x=x*10+ch-'0';
        ch=getchar();
    }
    if(ok) x=-x;
}

void task(int n,int k,int &x)
{
    if(!k)
    {
        x=0;
        return;
    }  
    long long t=(long long)k*k;  
    while(t>=d[n]) t=t/10;
    x=(int)t;
}  

int main()
{
    //freopen("in1.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    read(t);
    while(t--)
    {
        read(n);
        read(k);

        int k1=k,k2=k; 
        ans=k;
        do
        {
            task(n,k1,k1);
            task(n,k2,k2); ans=max(ans,k2);
            task(n,k2,k2); ans=max(ans,k2);
        }while(k1!=k2);

        printf("%d\n",ans);
    }  
    return 0;  
}

猜你喜欢

转载自blog.csdn.net/qq_35546348/article/details/52443174