二阶魔方又叫小魔方,是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
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\n",re);
return 0;
}