字节跳动2018校招后端方向(第三批)第二题
二阶魔方又叫小魔方,是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
输出例子1:
8281
题解:
DFS旋转操作,题不难,关键在于代码实现思路的清晰和简单。
#include <bits/stdc++.h> using namespace std; const long long INF = 0x3f3f3f3f3f3f3f3f; int board[30]; long long getSum(){ long long re = 0; re += board[0]*board[1]*board[2]*board[3]; re += board[4]*board[5]*board[10]*board[11]; re += board[6]*board[7]*board[12]*board[13]; re += board[8]*board[9]*board[14]*board[15]; re += board[16]*board[17]*board[18]*board[19]; re += board[20]*board[21]*board[22]*board[23]; return re; } void Swap(int a,int b,int c,int d){ int t = board[a]; board[a] = board[b]; board[b] = board[c]; board[c] = board[d]; board[d] = t; } void Right(){ Swap(1,7,17,21); Swap(3,13,19,23); Swap(8,14,15,9); } void Left(){ Swap(0,20,16,6); Swap(2,22,18,12); Swap(5,4,10,11); } void Up(){ Swap(6,8,23,4); Swap(7,9,22,5); Swap(0,2,3,1); } void Down(){ Swap(12,14,21,10); Swap(13,15,20,11); Swap(16,17,19,18); } void Front(){ Swap(2,11,17,8); Swap(3,5,16,14); Swap(6,12,13,7); } void Behind(){ Swap(0,9,19,10); Swap(1,15,18,4); Swap(20,22,23,21); } long long re; void DFS(int tp){ long long sum = getSum(); if(sum > re)re = sum; if(tp == 5)return; Right();//转一次顺时针 DFS(tp+1); Right();Right();//转三次就是逆时针 DFS(tp+1); Right(); Left(); DFS(tp+1); Left();Left(); DFS(tp+1); Left(); Up(); DFS(tp+1); Up();Up(); DFS(tp+1); Up(); Down(); DFS(tp+1); Down();Down(); DFS(tp+1); Down(); Front(); DFS(tp+1); Front();Front(); DFS(tp+1); Front(); Behind(); DFS(tp+1); Behind();Behind(); DFS(tp+1); Behind(); } int main(){ for(int i=0 ; i<24 ; ++i)scanf("%d",&board[i]); re = -INF; DFS(0); printf("%lld ",re); return 0; }