今日头条2018校招题目--二阶魔方(穷举加深搜)

题目描述

牛客网链接:(https://www.nowcoder.com/questionTerminal/73de370854f141a29749bb036ffd0298).
二阶魔方又叫小魔方,是222的立方形结构。每一面都有4个块,共有24个块。每次操作可以将任意一面逆时针或者顺时针旋转90°,如将上面逆时针旋转90°操作如下。
今日头条2018校招题目--二阶魔方(穷举加深搜)_第1张图片
Nero在小魔方上做了一些改动,用数字替换每个块上面的颜色,称之为数字魔方。魔方上每一面的优美度就是这个面上4个数字的乘积,而魔方的总优美度就是6个面优美度总和。
现在Nero有一个数字魔方,他想知道这个魔方在操作不超过5次的前提下能达到的最大优美度是多少。
魔方展开后每一块的序号如下图:
今日头条2018校招题目--二阶魔方(穷举加深搜)_第2张图片

输入描述:
输入一行包含24个数字,按序号顺序给出魔方每一块上面的数字。所有数大小范围为[-100,100]。
输出描述:
输出一行包含一个数字,表示最大优美度。
示例1
输入
复制
2 -3 -2 3 7 -6 -6 -7 9 -5 -9 -3 -2 1 4 -9 -1 -10 -5 -5 -10 -4 8 2
输出
复制
8281

解题思路

首先经过模拟我们了解到魔方的转动方法有六种:
1.顶层顺时针旋转(上下两个面不变,其他四个面改变,但是上下两个面的数字某一面对应的位置会发生变化)
2.顶层逆时针(相当于顶层顺时针旋转三次)
3.左侧顺时针(同1)
4.左侧逆时针(相当于3次2)
5.前面顺时针
6.前面逆时针(相当于3次5)

之后我们可以想到通过穷举加DFS搜索,设置一个全局变量maxScore,对于每一种方法,比较当前的得分和maxScore 的大小,最终得到最大值。
比较麻烦就是对于每一次的旋转,对应位置数字的变化,这个容易写错,要仔细一点

代码如下:

import java.util.*;
public class Main{
    static int maxScore = 0;
    static int[] nums = new int[24];
     
    static void judge(){
        int score = nums[0]*nums[1]*nums[2]*nums[3]+
            nums[6] * nums[7] * nums[12] * nums[13] +
            nums[16] * nums[17] * nums[18] * nums[19] +
            nums[20] * nums[21] * nums[22] * nums[23] +
            nums[4] * nums[5] * nums[10] * nums[11] +
            nums[8] * nums[9] * nums[14] * nums[15];
        if(score > maxScore)
            maxScore = score;
    }
     
    static void changeA(){ //顺时针旋转下面一个面
        int tmp = nums[6];
        nums[6] = nums[12];
        nums[12] = nums[13];
        nums[13] = nums[7];
        nums[7] = tmp;
         
        int tmp1 = nums[16],tmp2 = nums[17];
        nums[16] = nums[14];nums[17] = nums[8];
        nums[14] = nums[3];nums[8] = nums[2];
        nums[3] = nums[5];nums[2] = nums[11];
        nums[5] = tmp1;nums[11] = tmp2;
    }
     
    static void changeB(){ //逆时针旋转下面一个面
        changeA();
        changeA();
        changeA();
    }
     
    static void changeC(){
        int tmp = nums[0];
        nums[0] = nums[1];
        nums[1] = nums[3];
        nums[3] = nums[2];
        nums[2] = tmp;
         
        int tmp1 = nums[6],tmp2 = nums[7];
        nums[6] = nums[4];nums[7] = nums[5];
        nums[4] = nums[23];nums[5] = nums[22];
        nums[22] = nums[9];nums[23] = nums[8];
        nums[8] = tmp1;nums[9] = tmp2;
    }
     
    static void changeD(){
        changeC();
        changeC();
        changeC();
    }
     
    static void changeE(){
        int tmp = nums[4];
        nums[4] = nums[5];
        nums[5] = nums[11];
        nums[11] = nums[10];
        nums[10] = tmp;
         
        int tmp1 = nums[6],tmp2 = nums[12];
        nums[6] = nums[16];nums[12] = nums[18];
        nums[16] = nums[20];nums[18] = nums[22];
        nums[20] = nums[0];nums[22] = nums[2];
        nums[0] = tmp1;nums[2] = tmp2;
    }
     
    static void changeF(){
        changeE();
        changeE();
        changeE();
    }
     
    static void dfs(int deep){
        judge();
        if(deep == 5)
            return;
        changeA();  //第一种旋转方式
        dfs(deep+1);
        changeB(); // 恢复到开始状态
        changeB(); //第二种旋转方式
        dfs(deep + 1);
        changeA(); //恢复到开始状态
        changeC(); //第三种旋转方式
        dfs(deep + 1);
        changeD();
        changeD();
        dfs(deep + 1);
        changeC();
        changeE();
        dfs(deep + 1);
        changeF();
        changeF();
        dfs(deep + 1);
        changeE();  //注意::每次旋转之后都需要复原
    }
     
    public static void main(String[] args){
        Scanner ac = new Scanner(System.in);
        for(int i = 0;i < 24;i++)
            nums[i] = ac.nextInt();
        dfs(0);
        System.out.println(maxScore);
    }
}

你可能感兴趣的:(算法,java,dfs)