HDU4801 转魔方DFS模拟
Posted hesorchen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU4801 转魔方DFS模拟相关的知识,希望对你有一定的参考价值。
题目
给出一个两阶魔方的初始形态,一次可以将一个面转动90°
求在N(1<=N<=7)步内最多能拼成几个面。
题解
由于是两阶魔方,左边UP等于右边DOWN,因此共有6种转动方式。直接模拟即可,时间复杂度 O ( 6 7 × 12 ) O(6^7\\times 12) O(67×12)
代码
#include <bits/stdc++.h>
using namespace std;
int mp[][6] = {
//魔方展开图
{-1, -1, 0, 1, -1, -1},
{-1, -1, 2, 3, -1, -1},
{4, 5, 6, 7, 8, 9},
{10, 11, 12, 13, 14, 15},
{-1, -1, 16, 17, -1, -1},
{-1, -1, 18, 19, -1, -1},
{-1, -1, 20, 21, -1, -1},
{-1, -1, 22, 23, -1, -1},
};
pair<int, int> rev[30];
void init() //魔方位置-展开图坐标的映射
{
rev[0] = {0, 2};
rev[1] = {0, 3};
rev[2] = {1, 2};
rev[3] = {1, 3};
rev[4] = {2, 0};
rev[5] = {2, 1};
rev[6] = {2, 2};
rev[7] = {2, 3};
rev[8] = {2, 4};
rev[9] = {2, 5};
rev[10] = {3, 0};
rev[11] = {3, 1};
rev[12] = {3, 2};
rev[13] = {3, 3};
rev[14] = {3, 4};
rev[15] = {3, 5};
rev[16] = {4, 2};
rev[17] = {4, 3};
rev[18] = {5, 2};
rev[19] = {5, 3};
rev[20] = {6, 2};
rev[21] = {6, 3};
rev[22] = {7, 2};
rev[23] = {7, 3};
}
int get(int i) //取出这个位置的值
{
return mp[rev[i].first][rev[i].second];
}
void assign(int val, int pos) //把值val赋值给后者
{
mp[rev[pos].first][rev[pos].second] = val;
}
int n, ans;
bool cmp(int id1, int id2)
{
return get(id1) == get(id2);
}
void fuck()
{
int res = 0;
res += cmp(0, 1) && cmp(1, 2) && cmp(2, 3);
res += cmp(6, 7) && cmp(12, 13) && cmp(13, 7);
res += cmp(8, 9) && cmp(14, 15) && cmp(8, 14);
res += cmp(20, 21) && cmp(21, 22) && cmp(20, 23);
res += cmp(4, 5) && cmp(4, 10) && cmp(4, 11);
res += cmp(16, 17) && cmp(17, 18) && cmp(18, 19);
ans = max(ans, res);
}
void op1()
{
int tmp = get(15);
assign(get(9), 15);
assign(get(8), 9);
assign(get(14), 8);
assign(tmp, 14);
int tmp1 = get(23), tmp2 = get(21);
assign(get(1), 21);
assign(get(3), 23);
assign(get(7), 1);
assign(get(13), 3);
assign(get(17), 7);
assign(get(19), 13);
assign(tmp1, 19);
assign(tmp2, 17);
}
void op2()
{
int tmp = get(15);
assign(get(14), 15);
assign(get(8), 14);
assign(get(9), 8);
assign(tmp, 9);
int tmp1 = get(23), tmp2 = get(21);
assign(get(19), 23);
assign(get(17), 21);
assign(get(13), 19);
assign(get(7), 17);
assign(get(3), 13);
assign(get(1), 7);
assign(tmp1, 3);
assign(tmp2, 1);
}
void op3()
{
int tmp = get(0);
assign(get(2), 0);
assign(get(3), 2);
assign(get(1), 3);
assign(tmp, 1);
int tmp1 = get(4), tmp2 = get(5);
assign(get(6), 4);
assign(get(7), 5);
assign(get(8), 6);
assign(get(9), 7);
assign(get(23), 8);
assign(get(22), 9);
assign(tmp1, 23);
assign(tmp2, 22);
}
void op4()
{
int tmp = get(0);
assign(get(1), 0);
assign(get(3), 1);
assign(get(2), 3);
assign(tmp, 2);
int tmp1 = get(22), tmp2 = get(23);
assign(get(8), 23);
assign(get(9), 22);
assign(get(6), 8);
assign(get(7), 9);
assign(get(4), 6);
assign(get(5), 7);
assign(tmp1, 5);
assign(tmp2, 4);
}
void op5()
{
int tmp = get(22);
assign(get(23), 22);
assign(get(21), 23);
assign(get(20), 21);
assign(tmp, 20);
int tmp1 = get(4), tmp2 = get(10);
assign(get(1), 4);
assign(get(0), 10);
assign(get(15), 1);
assign(get(9), 0);
assign(get(18), 15);
assign(get(19), 9);
assign(tmp1, 18);
assign(tmp2, 19);
}
void op6()
{
int tmp = get(22);
assign(get(20), 22);
assign(get(21), 20);
assign(get(23), 21);
assign(tmp, 23);
int tmp1 = get(4), tmp2 = get(10);
assign(get(18), 4);
assign(get(19), 10);
assign(get(15), 18);
assign(get(9), 19);
assign(get(1), 15);
assign(get(0), 9);
assign(tmp1, 1);
assign(tmp2, 0);
}
void dfs(int step)
{
fuck();
if (step >= n)
return;
op1();
dfs(step + 1);
op2();
op2();
dfs(step + 1);
op1();
op3();
dfs(step + 1);
op4();
op4();
dfs(step + 1);
op3();
op5();
dfs(step + 1);
op6();
op6();
dfs(step + 1);
op5();
}
void input()
{
for (int i = 0; i <= 1; i++)
for (int j = 2; j <= 3; j++)
scanf("%d", &mp[i][j]);
for (int i = Week10 限时大模拟 B - 东东转魔方 HDU - 5983