首页 > 试题广场 >

附加题

[编程题]附加题
  • 热度指数:1885 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
二阶魔方又叫小魔方,是2*2*2的立方形结构。每一面都有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


import java.util.*;
import java.io.*;
 
public class Main {
    public static void main (String[] args) {
        record = new ArrayList<>();

        //魔方共有6种旋转方式。(逆时针旋转魔方的面朝你的一半等同于顺时针旋转魔方后侧的一半)
       //旋转一次发生两种变化,以上图为例:
        //假设面朝4,5,10,11,将面前的平面逆时针旋转90度
        //0,2,6,12,16,18,20,22编号的8个数字交换位置,结束后新的位置为6,12,16,18,20,22,0,2
        //4,5,11,10编号的4个数字变换位置,结束后新的位置为5,11,10,4
        //record里第一个int[]用于记录此次旋转会改变的所有数字
        //之后每个int[]各记录旋转一个平面后将改变的数字且遵从刚才的数字空间排列顺序

        record.add(new int[] {0,2,6,12,16,18,20,22,4,5,11,10}); 
        record.add(new int[] {1,3,7,13,17,19,21,23,8,14,15,9});
        record.add(new int[] {4,5,6,7,8,9,23,22,0,2,3,1});
        record.add(new int[] {10,11,12,13,14,15,21,20,16,17,19,18});
        record.add(new int[] {0,1,9,15,19,18,10,4,20,22,23,21});
        record.add(new int[] {2,3,8,14,17,16,11,5,6,7,13,12});
        Scanner s = new Scanner(System.in);
        String[] str_arr = s.nextLine().split(" ");
        int[] arr = new int[str_arr.length];
        for (int i=0; i<str_arr.length; i++) {
            arr[i] = Integer.parseInt(str_arr[i]);
        }
        //arr是初始魔方
        System.out.println(turn(arr, 5));
    }
     
    //l为魔方本身, remain为剩余旋转次数, 返回最多旋转remain次魔方的最大优美度
    private static int turn (int[] l, int remain) {
        //不可再旋转,返回当前优美度即可
        if (remain==0) {
            return mult(l);
        }
        int result = -99999;
        int temp;
        for (int[] r:record) {
            int[] n = l.clone();

            //根据record变换魔方内的值 
            temp = n[r[6]];
            for (int i=4; i>=0; i-=2) {
                n[r[i+2]] = n[r[i]];
            }
            n[r[0]] = temp;
            temp = n[r[7]];
            for (int i=5; i>=1; i-=2) {
                n[r[i+2]] = n[r[i]];
            }
            n[r[1]] = temp;
            temp = n[r[11]];
            for (int i=10; i>=8; i--) {
                n[r[i+1]] = n[r[i]];
            }
            n[r[8]] = temp;

            //使用新魔方进行remain-1次旋转
            temp = turn(n, remain-1);

            //取最大优美度
            if (temp>result) result = temp;
        }
        //返回最大优美度
        return Math.max(mult(l),result);
    }
     
    //计算单个魔方优美度
    private static int mult (int[] l) {
        return l[0]*l[1]*l[2]*l[3]+l[4]*l[5]*l[10]*l[11]+l[6]*l[7]*l[12]*l[13]+l[8]*l[9]*l[14]*l[15]
            +l[16]*l[17]*l[18]*l[19]+l[20]*l[21]*l[22]*l[23];
    }
     
    private static List<int[]> record;
}


编辑于 2021-03-04 20:47:47 回复(0)