HDU4801 转魔方DFS模拟

Posted hesorchen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU4801 转魔方DFS模拟相关的知识,希望对你有一定的参考价值。

题目

HDU 4801

给出一个两阶魔方的初始形态,一次可以将一个面转动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

HDU 5983(模拟魔方 模拟)

HDU 1998 奇数阶魔方模拟填数/注意边界和细节

东东转魔方(模拟)

东东转魔方(模拟)

2016ACM/ICPC亚洲区青岛站 B Hdu-5983 Pocket Cube 模拟