题目描述
牛客网链接:(https://www.nowcoder.com/questionTerminal/73de370854f141a29749bb036ffd0298).
二阶魔方又叫小魔方,是222的立方形结构。每一面都有4个块,共有24个块。每次操作可以将任意一面逆时针或者顺时针旋转90°,如将上面逆时针旋转90°操作如下。
Nero在小魔方上做了一些改动,用数字替换每个块上面的颜色,称之为数字魔方。魔方上每一面的优美度就是这个面上4个数字的乘积,而魔方的总优美度就是6个面优美度总和。
现在Nero有一个数字魔方,他想知道这个魔方在操作不超过5次的前提下能达到的最大优美度是多少。
魔方展开后每一块的序号如下图:
输入描述:
输入一行包含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);
}
}