牛牛的作业薄上有一个长度为 n 的排列 A,这个排列包含了从1到n的n个数,但是因为一些原因,其中有一些位置(不超过 10 个)看不清了,但是牛牛记得这个数列顺序对的数量是 k,顺序对是指满足 i < j 且 A[i] < A[j] 的对数,请帮助牛牛计算出,符合这个要求的合法排列的数目。
输入描述:
每个输入包含一个测试用例。每个测试用例的第一行包含两个整数 n 和 k(1 <= n <= 100, 0 <= k <= 1000000000),接下来的 1 行,包含 n 个数字表示排列 A,其中等于0的项表示看不清的位置(不超过 10 个)。
输出描述:
输出一行表示合法的排列数目。
输入例子:
5 5
4 0 0 2 0
输出例子:
2
思路:首先将模糊的数字统计出来,并求出这些数字的全排列,然后分别求已有的序列的排列对和新增模糊数字的排序对,将两个结果相加,如果等于k,则结果加1。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Scanner;
public class WangyiTest14 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
int n = scanner.nextInt();
int k = scanner.nextInt();
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = scanner.nextInt();
}
System.out.println(legalSortNum(n, k, a));
}
}
public static int legalSortNum(int n, int k, int[] a) {
int legalNum = 0;
ArrayList<Integer> fuzzyNumList = new ArrayList<Integer>();
boolean[] flag = new boolean[n + 1];
// flag标记哪些数字已经存在
for (int i = 0; i < n; i++) {
if (a[i] != 0) {
flag[a[i]] = true;
}
}
// 统计排列中不存在的数字
for (int i = 1; i <= n; i++) {
if (flag[i] == false) {
fuzzyNumList.add(i);
}
}
// fuzzyNumLists 用来存模糊数字的全排列
ArrayList<ArrayList<Integer>> fuzzyNumLists = new ArrayList<ArrayList<Integer>>();
permutation(fuzzyNumLists, fuzzyNumList, 0);
int curSortNum = 0;
// 统计已有的排列的顺序对
for (int i = 0; i < n - 1; i++) {
if (a[i] != 0) {
for (int j = i + 1; j < n; j++) {
if (a[j] != 0 && a[i] < a[j]) {
curSortNum++;
}
}
}
}
// 计算每个模糊数字排列的顺序对,加上已有的排列的顺序对,如果和k相等,则结果加1
for (ArrayList<Integer> list : fuzzyNumLists) {
int totalNum = curSortNum;
int[] copyA = Arrays.copyOf(a, n);
totalNum += fuzzySortNum(list, copyA);
if (totalNum == k) {
legalNum++;
}
}
return legalNum;
}
// 计算添加模糊集到数列里面时增加的排序对
public static int fuzzySortNum(ArrayList<Integer> list, int[] a) {
int sortNum = 0;
int count = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] == 0) {
a[i] = list.get(count++);// 每一个为0的位置 ,安插一个list中的模糊数字
for (int j = 0; j < i; j++) {
if (a[j] != 0 && a[j] < a[i]) {
sortNum++;
}
}
for (int j = i + 1; j < a.length; j++) {
if (a[j] != 0 && a[j] > a[i]) {
sortNum++;
}
}
}
}
return sortNum;
}
// 计算全排列的函数(工具类)
public static void permutation(ArrayList<ArrayList<Integer>> lists, ArrayList<Integer> list, int n) {
if (n == list.size()) {
lists.add(new ArrayList<Integer>(list));
} else {
for (int i = n; i < list.size(); i++) {
Collections.swap(list, i, n);
permutation(lists, list, n + 1);
Collections.swap(list, i, n);
}
}
}
}