思路:模拟
分析:
1 题目要求找到最大的n位数,那么我们通过不断的模拟,求出最大的ans
2 这里有个问题就是我们怎么知道什么时候结束呢?我们知道如果当前数已经有出现了那么说明刚好一个循环,这里利用map映射
代码:
#include<map>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n , k;
map<long long , int>mp;
int solve(){
long long num = k;
int ans = k;
mp.clear();
mp[num] = 1;
while(true){
num = num*num;
long long tmp = num;
int digit = 0;
while(tmp){
digit++;
tmp /= 10;
}
long long pow = 1;
for(int i = 1 ; i <= digit-n ; i++)
pow *= 10;
num /= pow;
ans = max((long long)ans , num);
if(mp[num])
return ans;
mp[num] = 1;
}
}
int main(){
int Case;
scanf("%d" , &Case);
while(Case--){
scanf("%d%d" , &n , &k);
printf("%d\n" , solve());
}
return 0;
}
法二:利用floyd判圈法
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long int64;
int n , k;
int64 next(int64 num){
int64 tmp = num*num;
int digit = 0;
while(tmp){
digit++;
tmp /= 10;
}
int64 pow = 1;
for(int i = 1 ; i <= digit-n ; i++)
pow *= 10;
return (num*num)/pow;
}
int solve(){
int ans = k;
int64 num1 = k , num2 = k;
while(true){
num1 = next(num1);
ans = max((int64)ans , num1);
num2 = next(num2);
ans = max((int64)ans , num2);
num2 = next(num2);
ans = max((int64)ans , num2);
if(num1 == num2)
return ans;
}
}
int main(){
int Case;
scanf("%d" , &Case);
while(Case--){
scanf("%d%d" , &n , &k);
printf("%d\n" , solve());
}
return 0;
}