牛客网 字节跳动算法题-二阶魔方最大优美度

该博客讨论了如何通过DFS算法解决二阶数字魔方在不超过5次旋转操作下达到最大优美度的问题。博主详细介绍了问题背景、魔方结构、旋转规则,并提供了一个Java实现的解决方案,包括旋转数组、计算优美度和深度优先搜索等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

描述

二阶魔方又叫小魔方,是222的立方形结构。每一面都有4个块,共有24个块。每次操作可以将任意一面逆时针或者顺时针旋转90°,如将上面逆时针旋转90°操作如下。
在这里插入图片描述
Nero在小魔方上做了一些改动,用数字替换每个块上面的颜色,称之为数字魔方。魔方上每一面的优美度就是这个面上4个数字的乘积,而魔方的总优美度就是6个面优美度总和。
现在Nero有一个数字魔方,他想知道这个魔方在操作不超过5次的前提下能达到的最大优美度是多少。
魔方展开后每一块的序号如下图:
在这里插入图片描述

输入描述:

输入一行包含24个数字,按序号顺序给出魔方每一块上面的数字。所有数大小范围为[-100,100]。

输出描述:

输出一行包含一个数字,表示最大优美度。

题解:

魔方的旋转会使得数组的值进行交换。每次旋转变动的是一周8个数字,和旋转面4个数字。
此为二阶魔方,只需考虑3个面的旋转情况;
旋转有顺时针旋转和逆时针旋转,不过顺时针(逆时针)旋 转可以通过旋转3次逆时针(顺时针)得到。
因此根据旋转规律声明turn旋转数组
考察DFS算法,深搜每种旋转情况,旋转完成计算一次当前最大优美度。

import java.util.*;
public class Main{
    public static int [][] turn = {
        //三面逆时针旋转,数组中每四个为一组
        {0,1,3,2,7,5,22,9,6,4,23,8},
        {6,7,13,12,2,8,17,11,3,14,16,5},
        {4,5,11,10,0,6,16,20,2,12,18,22},
    };
    public static int max = Integer.MIN_VALUE;
    public static void main(String []args){
        Scanner scanner = new Scanner(System.in);
        int[] n = new int[24];
        for(int i = 0; i < 24; i++) {
            n[i] = scanner.nextInt();
        }
        dfs(n, 0);
        System.out.println(max);
    }
    public static void dfs(int[] n, int depth) {
        // 非法状态
        if (depth == 6) return ;
        // 当前状态优美度
        int res = compute(n);
        max = Math.max(res,max);
        //逆时针旋转
        for (int i = 0; i < 3; i++) {
            swap(n,i);
            //旋转完成进入下一层
            dfs(n,depth+1);
            swap(n,i);
            swap(n,i);
            swap(n,i);
        }
        //顺时针旋转
        for (int j = 0; j < 3; j++) {
            swap(n,j);
            swap(n,j);
            swap(n,j);
            //旋转完成进入下一层
            dfs(n,depth+1);
            swap(n,j);
        }
    }
    //每次旋转后交换数组的值
    public static void swap (int[] n,int type) {
        // 每四个下标一轮回
        for (int i = 0, tmp = 0; i < 12; i++) {
            if (i % 4 == 0) tmp = n[turn[type][i]];
            if (i % 4 == 3) n[turn[type][i]] = tmp;
            else n[turn[type][i]] = n[turn[type][i+1]];
        }
    }
    //计算优美度
    public static int compute (int[] n) {
        return n[0]*n[1]*n[2]*n[3] +
               n[6]*n[7]*n[12]*n[13] +
               n[4]*n[5]*n[10]*n[11] +
               n[8]*n[9]*n[14]*n[15] +
               n[16]*n[17]*n[18]*n[19] +
               n[20]*n[21]*n[22]*n[23];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值