链接
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2544
题解1
肯定有循环节啊,要不然还做个毛
直接暴力模拟
500000
500000
次,统计最大值
题解2
刘汝佳的题解竟然用
string
s
t
r
i
n
g
判重,我也是醉了
他补充的一个算法很好,
floyd
f
l
o
y
d
判环,用两条线路,一条线路每次模拟两次计算,另一条线路每次模拟一次计算,当
k1=k2
k
1
=
k
2
时,说明找到了循环节,这样为啥对呢?如何确保
k2
k
2
不会直接跳过
k1
k
1
?
设
k1
k
1
走了
x
x
步
所以没问题
显然时间复杂度复杂度就是 O( O ( 循环节长度 ) ) <script type="math/tex" id="MathJax-Element-12">)</script>
刘汝佳也没有证明循环节长度的大小,我也不会,有谁会吗?请在评论区留言
代码1
#include <cstdio>
#include <algorithm>
#define ll long long
using namespace std;
int main()
{
ll n, k, mi, i, T, m;
for(scanf("%lld",&T);T;T--)
{
scanf("%lld%lld",&n,&k);
for(i=mi=1;i<=n;i++)mi*=10;
m=k;
for(i=1;i<=500000;i++)
{
for(k*=k;k>=mi;k/=10);
m=max(m,k);
}
printf("%lld\n",m);
}
return 0;
}
代码2
#include <cstdio>
#include <algorithm>
#define ll long long
using namespace std;
ll mi, m;
ll step(ll k)
{
ll i;
for(k*=k;k>=mi;k/=10);
m=max(m,k);
return k;
}
int main()
{
ll n, k1, i, T, k2, k;
for(scanf("%lld",&T);T;T--)
{
scanf("%lld%lld",&n,&k);
for(i=mi=1;i<=n;i++)mi*=10;
for(m=k1=k,k2=step(step(k));k1^k2;k1=step(k1), k2=step(step(k2)));
printf("%lld\n",m);
}
return 0;
}