题目地址:https://ac.nowcoder.com/acm/contest/5670?&headNav=www#question
E:Bogo Sort
题意:给你
n
n
n个数,这是一个置换,问你
1
−
n
1-n
1−n的全排列有多少个排列通过这个置换可以得到递增的序列。
例(样例
2
2
2的解释):
样例
2
2
2给你的置换是
2 3 4 5 6 1
意思是:
每一次变换,
a
[
]
a[]
a[]里的第一个数移到第二位,
第二个数移到第三位,
…
第六个数移到第一位。
所以,通过以上变换可以得到递增顺序的序列是:
(1)1 2 3 4 5 6
(2)2 3 4 5 6 1
(3)3 4 5 6 1 2
(4)4 5 6 1 2 3
(5)5 6 1 2 3 4
(6)6 1 2 3 4 5
思路:
通过题目给的置换,我们可以得到很多的“闭环”,比如样例
2 1 6 3 5 4
我们模拟一遍所有的位置的变换过程,如下:
1 -> 2 -> 1
3 -> 6 -> 4 -> 3
5 -> 5
那么所有变换长度的
l
c
m
lcm
lcm就是答案。
如上的答案便是
l
c
m
(
2
,
3
,
1
)
=
6
lcm(2,3,1) = 6
lcm(2,3,1)=6。
由于题目给的数很大,所以可以用
J
a
v
a
Java
Java大数来写。
代码如下:
import java.util.Scanner;
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
int a[] = new int[100010];
boolean vis[] = new boolean[100010];
Scanner input = new Scanner(System.in);
int n = input.nextInt();
for(int i = 1 ; i <= n ; i++) {
a[i] = input.nextInt();
vis[i] = false;
}
BigInteger ans = BigInteger.ONE;
for(int i = 1 ; i <= n ; i++) {
if(vis[i] != true) {
int x = i;
int num = 0;
// System.out.println("x = " + x);
while(vis[x] == false){
vis[x] = true;
x = a[x];
num++;
}
BigInteger GCD = ans.gcd(new BigInteger(String.valueOf(num)));
ans = ans.multiply(new BigInteger(String.valueOf(num)));
ans = ans.divide(GCD);
}
}
System.out.println(ans);
}
}