题解 | #多多的骰子组合#
多多的骰子组合
http://www.nowcoder.com/questionTerminal/27086d759f01413b94a1a30a53e4a333
容易理解的思路,固定魔方,代码多但容易
import java.util.*;
public class Main {
// 思路:把数字1翻转到前面,在这个前提下,再把数字2翻转到左边,如果数字2在后面就把数字3翻转到左边
// 这样就算是固定了魔方,关键在于翻转魔方,其余操作都很简单,代码多但是很容易
public static void main(String[] args) {
handler();
}
// 上0、下1、左2、右3、前4、后5
// 核心代码看懂这里就行~~~
public static Map<String, Integer> fun(int[][] arr) {
Map<String, Integer> map = new HashMap<>(); // <魔方,出现次数>
for (int[] saizi : arr) {
revertOneToFront(saizi);
revertTwoToLeftOrThreeToLeft(saizi);
String str = join(saizi, "");
map.put(str, map.getOrDefault(str, 0) + 1);
}
return map;
}
private static void handler() {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[][] arr = new int[n][];
for (int i = 0; i < n; i++) {
arr[i] = new int[6];
for (int k = 0; k < 6; k++)
arr[i][k] = in.nextInt();
}
// 输出结果
Map<String, Integer> map = fun(arr);
System.out.println(map.size());
Integer[] res = new Integer[map.size()];
int ptr = 0;
for (Integer count : map.values())
res[ptr++] = count;
Arrays.sort(res, (a, b) -> {
return b - a;
});
for (Integer val : res)
System.out.print(val + " ");
}
// 将数字1翻转到前面位置
private static void revertOneToFront(int[] arr) {
if (arr[0] == 1) {
revertRight2(arr);
} else if (arr[1] == 1) {
revertRight1(arr);
} else if (arr[2] == 1) {
revertUp2(arr);
} else if (arr[3] == 1) {
revertUp1(arr);
} else if (arr[5] == 1) {
revertRight1(arr);
revertRight1(arr);
}
}
// 前面为1的前提下,将数字2翻转到左边,如果数字2在后面就吧数字3翻转到左边
private static void revertTwoToLeftOrThreeToLeft(int[] arr) {
// 上0、下1、左2、右3、前4、后5
if (arr[0] == 2) {
revertFront2(arr);
} else if (arr[1] == 2) {
revertFront1(arr);
} else if (arr[3] == 2) {
revertFront1(arr);
revertFront1(arr);
} else if (arr[5] == 2) {
// 前后分别是1和2,吧3翻转到左边
if (arr[0] == 3) {
revertFront2(arr);
} else if (arr[1] == 3) {
revertFront1(arr);
} else if (arr[3] == 3) {
revertFront1(arr);
revertFront1(arr);
}
}
}
// 面向上-顺时针翻转魔方90度
private static void revertUp1(int[] arr) {
revert(arr, 4, 3, 5, 2); // 前右后左
}
// 上逆
private static void revertUp2(int[] arr) {
revert(arr, 4, 2, 5, 3);
}
// 前顺
private static void revertFront1(int[] arr) {
revert(arr, 0, 2, 1, 3);
}
// 前逆
private static void revertFront2(int[] arr) {
revert(arr, 0, 3, 1, 2);
}
// 右顺
private static void revertRight1(int[] arr) {
revert(arr, 0, 4, 1, 5);
}
// 右逆
private static void revertRight2(int[] arr) {
revert(arr, 0, 5, 1, 4);
}
// 翻转魔方,如果顺时针旋转就逆时针传入4个面
private static void revert(int[] arr, int face1, int face2, int face3, int face4) {
swap(arr, face1, face2);
swap(arr, face2, face3);
swap(arr, face3, face4);
}
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// 将数组序列化
private static String join(int[] arr, String split) {
StringBuilder str = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
str.append(arr[i]);
if (i != arr.length - 1)
str.append(split);
}
return str.toString();
}
}