题目链接 :E.Bogo Sort
前几天刚看过群论,所以今天这道题转换为群论后能立刻反应写出,只不过本题要求大数运算,所以用java写完A了。
题意
给你n个数的一种排列组合,问你通过题目给的排序算法,至少需要多少次变换能够转换为1~n的序列。
题解
通过这个核心代码可以看出,题目给的算法就是一种置换,最初的为T,问你k为多少时,
T
k
=
e
{T^k=e}
Tk=e,e为单元置换也就是1,2,3…n。
和Permutations POJ - 2369如出一辙
唯一不同的是需要对
1
0
n
{10^n}
10n取模,n的范围
1
≤
N
≤
1
0
5
{1≤N≤10^5}
1≤N≤105,所以一般的数据类型是无法存储
1
0
n
{10^n}
10n这样大的数字。所以用java大数BigInteger可以解决此类问题。
代码
import java.math.BigInteger;
import java.util.*;
public class Main {
public static int f[] = new int[100005];
public static BigInteger cnt[] = new BigInteger[100005];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
BigInteger r=BigInteger.ONE;
for(int i=1;i<=n;i++)
r=r.multiply(BigInteger.valueOf(10));
for (int i = 1; i <= n; i++)
f[i] = i;
for(int i=1;i<=100000;i++)
cnt[i]=BigInteger.ZERO;
for (int i = 1; i <= n; i++) {
int x;
x = sc.nextInt();
if (find(i) != find(x)) f[x] = i;
}
for (int i = 1; i <= n; i++)
cnt[find(i)] = cnt[find(i)].add(BigInteger.ONE);
BigInteger ans = BigInteger.ONE;
for (int i = 1; i <= n; i++) {
if (cnt[i]!=BigInteger.ZERO)
{
ans = lcm(ans, cnt[i]);
}
}
System.out.println(ans.mod(r));
}
public static int find(int x) {
if (x == f[x])
return x;
else
return f[x] = find(f[x]);
}
public static BigInteger lcm(BigInteger a, BigInteger b) {
return a.multiply(b).divide(a.gcd(b));
}
}