UVaLive 3401 Colored Cubes 彩色立方体

题意:有n个带颜色的立方体,每个立方体每个面都涂有一种颜色。要求重新涂尽量少的面,使得所有立方体完全相同。两个立方体完全相同是指存在一种旋转方式,使得这两个立方体对应面颜色完全一样。




很暴力的题。首先每个立方体经过旋转,只有24种不同的状态(先选一个面作为前面,6种选法,然后选一个面作为上面,4种选法。共6*4 = 24种)。而n最大只有4,而且两个立方体经过旋转可以完全相同的话,我们可以一个立方体不动作为参照。这样只需要枚举最多3个立方体的所有状态,也就是最多24^3种状态组合。然后每个状态下比较所有立方体的每个面,对于每个面找出颜色相同的面的最大值,这些面都不重新涂,而重新涂剩下与他们不同颜色的面。这样复杂度是O(24^(n - 1)*n*6)可以通过这个题。




#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
using namespace std;

//定义24种状态的6个面编号,第二维0-5分别表示上、下、左、右、前、后面的编号
const int state[24][6] =
{
    {1, 6, 2, 5, 3, 4}, {1, 6, 3, 4, 5, 2}, {1, 6, 5, 2, 4, 3}, {1, 6, 4, 3, 2, 5},
    {6, 1, 2, 5, 4, 3}, {6, 1, 4, 3, 5, 2}, {6, 1, 5, 2, 3, 4}, {6, 1, 3, 4, 2, 5},
    {2, 5, 6, 1, 3, 4}, {2, 5, 3, 4, 1, 6}, {2, 5, 1, 6, 4, 3}, {2, 5, 4, 3, 6, 1},
    {5, 2, 1, 6, 3, 4}, {5, 2, 3, 4, 6, 1}, {5, 2, 6, 1, 4, 3}, {5, 2, 4, 3, 1, 6},
    {3, 4, 2, 5, 6, 1}, {3, 4, 6, 1, 5, 2}, {3, 4, 5, 2, 1, 6}, {3, 4, 1, 6, 2, 5},
    {4, 3, 2, 5, 1, 6}, {4, 3, 1, 6, 5, 2}, {4, 3, 5, 2, 6, 1}, {4, 3, 6, 1, 2, 5},
};
const int MAX = 30;

int n;
char cube[5][6][MAX];
map <string, int> ma[6];

void input()
{
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < 6; j++)
            scanf("%s", cube[i][j]);
    }
}

void solve()
{
    int total = 1; //存储一共的状态组合
    int ans = 24; //初始化最大值
    for(int i = 1; i < n; i++) //i从1开始,第一个立方体不用旋转,作为参考系即可
        total *= 24;
    int cnt[6];
    while(total--)
    {
        memset(cnt, 0, sizeof(cnt));
        for(int i = 0; i < 6; i++)
            ma[i].clear();
        int temp = total;
        for(int i = 0; i < n; i++)
        {
            int pos = temp%24; //24进制法求每个立方体的状态
            temp /= 24;
            for(int j = 0; j < 6; j++)
                cnt[j] = max(cnt[j], ++ma[j][cube[i][state[pos][j] - 1]]); // -1是因为数组下标对应问题
        }
        int temp_ans = 0;
        for(int i = 0; i < 6; i++)
            temp_ans += n - cnt[i];
        ans = min(ans, temp_ans);
    }
    printf("%d\n", ans);
}

int main()
{
    while(scanf("%d", &n) && n != 0)
    {
        input();
        solve();
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章