UVA11549计算器谜题

老榆

关注

阅读 46

2022-07-27

题意:
       有一个计算机只能保留数字的前n位,你有一个数字k(k<=9),反复平方后在计算机上显示的最大数字是多少。


思路:
      显然这个题目是有循环节的,为什么有循环节?首先我们看下k<=9那么也就是说所有的答案都是9位数之内的,也就是说才几亿呗,最慢几亿次之后必然循环啊,这样我们就可以不停得枚举,然后碰到循环节的时候就不枚举了,怎么样找循环节,一开始想的是只记录第一个,然后等第一个再次出现的时候就直接break结果果断错了,他有可能是类似这样的循环节1 2 3 4 5 4 5 4 5.....循环节是4 5,这种的,所以第一种方法失败了,但是我们可以用最笨的方法去记录,就是开一个容器,我开的是map,记录每个数字是否出现过,提交之后虽然ac了但感觉容器挺耗时的,然后又写了个书上说的那个Floyd判圈,结果果然快了很多,一下是两种方法的代码。




Floyd判圈

#include<stdio.h>



int mk[15];



void inint()

{

mk[0] = 1;

for(int i = 1 ;i <= 9 ;i ++)

mk[i] = mk[i-1] * 10;

}



long long next(int n ,int a)

{

long long now = (long long)a * (long long)a;

while(now >= mk[n])

now /= 10;

return int(now);

}



int main ()

{

int t ,n ,m ,Ans;

inint();

scanf("%d" ,&t);

while(t--)

{

scanf("%d %d" ,&n ,&m);

Ans = m;

int k1 = m ,k2 = m;

do

{

k1 = next(n ,k1);if(Ans < k1) Ans = k1;

k2 = next(n ,k2);if(Ans < k2) Ans = k2;

k2 = next(n ,k2);if(Ans < k2) Ans = k2;

}while(k1 != k2);

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

}

return 0;

}





map判断是否出现过



#include<stdio.h>

#include<map>



using namespace std;



int mk[15];

map<int ,int>mark;



void inint()

{

mk[0] = 1;

for(int i = 1 ;i <= 9 ;i ++)

mk[i] = mk[i-1] * 10;

}



long long next(int n ,int a)

{

long long now = (long long)a * (long long)a;

while(now >= mk[n])

now /= 10;

return int(now);

}



int main ()

{

int t ,n ,m ,Ans;

inint();

scanf("%d" ,&t);

while(t--)

{

scanf("%d %d" ,&n ,&m);

Ans = m;

mark.clear();

mark[m] = 1;

while(1)

{

m = next(n ,m);

if(Ans < m) Ans = m;

if(mark[m]) break;

mark[m] = 1;

}

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

}

return 0;

}


            












            



精彩评论(0)

0 0 举报