题解 | #多多的骰子组合#

多多的骰子组合

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();
    }
}
全部评论

相关推荐

1 收藏 评论
分享
牛客网
牛客企业服务