题目描述
给定两个只包含数字的数组a, b, 调整数组a里面数字的顺序,使得尽可能多的a[i] > b[i]。数组a和b中的数字各不相同。
输出所有可以达到最优结果的a数组数量
输入描述
输入的第一行是数组a中的数字,其中只包含数字,每两个数字之间相隔一个空格,a数组大小不超过10
输入的第二行是数组b中的数字,其中只包含数字,每两个数字之间相隔一个空格,b数组大小不超过10
输出描述
输出所有可以达到最优结果的a数组数量
示例1
输入
11 8 20
10 13 7
输出
1
说明
最优结果只有一个,a = [11, 20, 8],故输出1
示例2
输入
11 12 20
10 13 7
输出
2
说明
有两个a数组的排列可以达到最优结果,[12, 20, 11]和[11, 20, 12],故输出2
示例3
输入
1 2 3
4 5 6
输出
6
说明
a无论如何都会全输,故a任意排列都行,输出所有a数组的排列,6种排法
思路
- 暴力解法
- 先用田忌赛马求出 一个出马顺序, 记录胜场数量。
- 全排列a马: 回溯算法。
代码
public class Demo06 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String line1 = in.nextLine();
List<Integer> a = Arrays.stream(line1.split(" ")).mapToInt(Integer::parseInt).boxed().collect(Collectors.toList());
String line2 = in.nextLine();
List<Integer> b = Arrays.stream(line2.split(" ")).mapToInt(Integer::parseInt).boxed().collect(Collectors.toList());
Collections.sort(a);
// 假设b会顺序出马
Collections.sort(b);
List<Integer> horse = horse(a, b);
int winCount = winCount(horse, b);
// 回溯算法
boolean[] visited = new boolean[horse.size()];
List<Integer> path = new ArrayList<>();
// 全排列结果
List<List<Integer>> res = new ArrayList<>();
backTracking(horse, visited, path, res);
int count = 0;
for (List<Integer> re : res) {
if (winCount == winCount(re, b)) {
count++;
}
}
System.out.println(count);
in.close();
}
// 田忌赛马 以b为基准,调整a
public static List<Integer> horse(List<Integer> a, List<Integer> b) {
List<Integer> aHorse = new ArrayList<>();
for (int i = b.size() - 1; i >= 0; i--) {
if (a.get(a.size() - 1) > b.get(i)) {
// 出大马
aHorse.add(a.get(a.size() - 1));
a.remove(a.size() - 1);
} else {
//出个小马应付下
aHorse.add(a.get(0));
a.remove(0);
}
}
Collections.reverse(aHorse);
return aHorse;
}
// 计算胜场
public static int winCount(List<Integer> a, List<Integer> b) {
int win = 0;
for (int i = 0; i < a.size(); i++) {
if (a.get(i) > b.get(i)) {
win++;
}
}
return win;
}
// 回溯算法全排列
public static void backTracking(List<Integer> a, boolean[] visited, List<Integer> path, List<List<Integer>> res) {
if (path.size() == a.size()) {
res.add(new ArrayList<>(path));
return;
}
for (int i = 0; i < a.size(); i++) {
if (visited[i]) {
continue;
}
visited[i] = true;
path.add(a.get(i));
backTracking(a, visited, path, res);
path.remove(path.size() - 1);
visited[i] = false;
}
}
}