2020牛客暑假多校第5场

题目地址:https://ac.nowcoder.com/acm/contest/5670?&headNav=www#question

E:Bogo Sort

题意:给你 n n n个数,这是一个置换,问你 1 − n 1-n 1n的全排列有多少个排列通过这个置换可以得到递增的序列。
例(样例 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);
    }
}

你可能感兴趣的:(比赛套题,学习笔记,思维)