头条机试 二阶魔方

二阶魔方每次操作可以将任意一面逆时针或者顺时针旋转90°,如将上面逆时针旋转90°操作如下。

魔方上每一面的优美度就是这个面上4个数字的乘积,而魔方的总优美度就是6个面优美度总和。
现在Nero有一个数字魔方,他想知道这个魔方在操作不超过5次的前提下能达到的最大优美度是多少。

魔方展开后每一块的序号如下图:


输入:

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

 

基本思路:

初始化一个24大小的数组 存放对应的数字

可以映射出对应每个面的数字组合

每一次转换,只需要将相应的数字交换即可(实际实现 通过一个中间数组),6个面总共有6类转换(逆时针通过三次正向转换)

从原始输入开始,BFS宽度优先搜索,没出现一次新的类别,计算当前的优雅度,更新res

 

face为对应6个面的数字序号   trans对应转换后每个位置对应原先哪个位置

int arr[24];//24小面
int res = 0;
int face[6][4]
=
{
{0,1,2,3},
{4,5,10,11},
{6,7,12,13},
{8,9,14,15},
{16,17,18,19},
{20,21,22,23}

};

//存放6次面的旋转  每一次旋转后对应位置是原先那个序号的值
int trans[6][24] =
{
	{0, 1, 11, 5, 4, 16, 12, 6, 2, 9, 10, 17, 13, 7, 3, 15, 14, 8, 18, 19, 20, 21, 22, 23},
	//BEHIND
	{9, 15, 2, 3, 1, 5, 6, 7, 8, 19, 0, 11, 12, 13, 14, 18, 16, 17, 4, 10, 22, 20, 23, 21},
	//LEFT
	{20, 1, 22, 3, 10, 4, 0, 7, 8, 9, 11, 5, 2, 13, 14, 15, 6, 17, 12, 19, 16, 21, 18, 23},
	//RIGHT
	{0, 7, 2, 13, 4, 5, 6, 17, 14, 8, 10, 11, 12, 19, 15, 9, 16, 21, 18, 23, 20, 1, 22, 3},
	//UP
	{2, 0, 3, 1, 6, 7, 8, 9, 23, 22, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 5, 4},
	//DOWN
	{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 21, 20, 10, 11, 12, 13, 18, 16, 19, 17, 15, 14, 22, 23}

};

 

核心函数  sum()求解和  trans_fun()实现转换  

 

int sum()
{
	int res = 0;
	for (int i = 0; i < 6; i++)//6个面相加
	{
		int tmp = 1;
		for (int j = 0; j < 4; j++)//4个数字相乘
		{
			tmp *= arr[face[i][j]];

		}

		res += tmp;
	}
	return res;

}

void trans_fun(int i)
{
	vector<int> tmp;
	for (int k = 0; k < 24; k++)
		tmp.push_back(arr[k]);
	for (int j = 0; j < 24; j++)
		arr[j] = tmp[trans[i][j]];

}

 

BFS搜索过程,通过执行三次trans_fun()  实现逆时针转换,易错点  需要通过4次trans_fun()实现递归的返回改回

void dfs(int depth)
{
	if (depth == 0)
		return;
	for (int j = 0; j < 6; j++)  //顺时针
	{

		trans_fun(j);  //每操作完一次  相当于新的组合  更新一次res
		res = max(res, sum());
		dfs(depth - 1);
		trans_fun(j);
		trans_fun(j);
		res = max(res, sum());
		dfs(depth - 1);
		trans_fun(j);


	}


}


int main()
{
	for (int i = 0; i < 24; i++)
		cin >> arr[i];
	res = sum();
	
	dfs(5);
	cout << res << endl;


}

 

 

 

 

 

 

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值