原题地址:http://nyoj.top/problem/52
这几天无意中看到的Floyd判圈法实在是好用,用于判断在于给定规则下是否会出现循环,这题是判断是否是按周期出现的,如果还不了解差别看下面的例子
10 3
分别是 10 100 0 0 0~~
这种就不是周期出现的。
再来说说这种算法吧,在时间复杂度上是差不多的,但是亮点在于空间复杂度O(1);怎么实现的呢?
我们先想像一个圆形的跑道,有两个人从同一起点开始跑,但是第二个人的速度是第一个人的两倍。那么如果有环会出现什么结果呢?第一个人跑完一圈的时侯第二个人恰好和它在同一水平线上,简单是说就是相遇(速度是两倍呀)
那具体怎么实现呢,首先我们把变换的规则封装成一个函数,定义两个变量n1,n2,让他们都等于初值,然后嘞?速度是两倍怎么实现呢???思考一下再来看看下面的代码吧;

#include<bits/stdc++.h>
using namespace std;
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define _for(n,m,i) for (int i = (n); i < (m); i++)
#define _rep(n,m,i) for (int i = (n); i <= (m); i++)
typedef long long LL;
LL Mod, n;
LL Next(LL x) {
  return x * n % Mod;
}
int main() {
  fio
  int t, k;
  cin >> t;
  while(t--) {
    cin >> n >> k;
    Mod = 1;
    while(k--) Mod *= 10;
    LL n1 = Next(1), n2 = Next(1);
    LL ans = n1;
    int num = 0;
    do{
      n1 = Next(n1);
      n2 = Next(n2);
      n2 = Next(n2);
      num++;
    }while(n1 != n2);
    if(n1 == ans) cout << num << endl;//判读是否是周期只需要看看结束点是不是在“起点”
    else cout << -1 << endl;
  }
}