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;
}


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