Colored Cubes UVALive

vj传送门

题意:给你n个正方体的六个面颜色, 问最少涂多少次让他们都变成颜色一样的正方体

解: 根据题目给的位置 1 2 3 4 5 6 (正面 右面 顶面 底面 左面 后面),可以用两种旋转方式(左旋、上旋)来枚举 一个正方体的所有旋转后的姿态  比如说选定一个为顶面  向左旋转四次就是 以他为顶面的所有姿态, 然后用这个方法枚举六个面在顶面的情况 , 最后输出一个数组,这个数组就是一个正方体的24种可能形态, 然后把输入的n个正方体开始枚举每个正方体的形态和每个视图需要涂的面数, 最后取最小即可,

 ( 只定义了两种旋转方式是因为看了书,如果想定义四种 上下左右旋转也是可以的)

  顶面为1, 需要标准姿态向上转三圈

  顶面为2, 需要标准姿态向左转一圈,向上转一圈

  顶面为3, 已经是标准姿态

  顶面为4, 需要标准姿态向上转两圈

  顶面为5, 需要标准姿态向左转一圈,向上转三圈

  顶面为6, 需要标准姿态向上转一圈

#include <bits/stdc++.h>

using namespace std;

#define _for(i,a,b) for(int i = (a); i < (b); i++)
#define _rep(i,a,b) for(int i = (a); i <= (b); i++)
#define ll long long
#define all(v) (v).begin(), (v).end()

int up[] = {2,1,5,0,4,3};
int letf[] = {4,0,2,3,5,1};
void rot(int* a, int* p) {
    int p0[6];
    memcpy(p0, p, sizeof(p0));
    _for(i,0,6) p[i] = a[p0[i]];
    return;
}
void qdice() {
    int p0[] = {0,1,2,3,4,5};
    _for(i,0,6) {
        int p[6]; 
        memcpy(p, p0, sizeof(p));
                
        if(i == 0) {rot(up,p); rot(up,p); rot(up,p);}
        else if(i == 1) {rot(letf,p); rot(up,p);}
        else if(i == 2) {}
        else if(i == 3) {rot(up,p); rot(up,p);}
        else if(i == 4) {rot(letf,p); rot(up,p); rot(up,p); rot(up,p);}
        else {rot(up,p);}
        
        _for(j,0,4) {
            rot(letf, p);
            cout << "{ ";
            _for(i,0,5) cout << p[i] << ", ";
            cout << p[5] << "},
";
        }
    }
    return; 
}

int dice[24][6] = {{ 3, 0, 4, 1, 5, 2},{ 3, 4, 5, 0, 1, 2},{ 3, 5, 1, 4, 0, 2},{ 3, 1, 0, 5, 4, 2},
{ 5, 2, 1, 4, 3, 0},{ 1, 2, 0, 5, 3, 4},{ 0, 2, 4, 1, 3, 5},{ 4, 2, 5, 0, 3, 1},
{ 4, 0, 2, 3, 5, 1},{ 5, 4, 2, 3, 1, 0},{ 1, 5, 2, 3, 0, 4},{ 0, 1, 2, 3, 4, 5},
{ 1, 0, 3, 2, 5, 4},{ 0, 4, 3, 2, 1, 5},{ 4, 5, 3, 2, 0, 1},{ 5, 1, 3, 2, 4, 0},
{ 5, 3, 4, 1, 2, 0},{ 1, 3, 5, 0, 2, 4},{ 0, 3, 1, 4, 2, 5},{ 4, 3, 0, 5, 2, 1},
{ 2, 0, 1, 4, 5, 3},{ 2, 4, 0, 5, 1, 3},{ 2, 5, 4, 1, 0, 3},{ 2, 1, 5, 0, 4, 3}};
vector<string> col;
int ID(string s) {
    int m = col.size();
    _for(i,0,m) if(s == col[i]) return i;
    col.push_back(s);
    return m;
}
int m[6][6],r[6],ans,n;

void check() {
    int color[24][6];
    _for(i,0,n) _for(j,0,6) 
        color[i][j] = m[i][dice[r[i]][j]];
        //color[i][dice[r[i]][j]] = m[i][j];
    int c[24], res = 0;
    _for(i,0,6) {
        int ma = 0;
        memset(c, 0, sizeof c);
        _for(j,0,n) ma = max(ma, ++c[color[j][i]]);
        res += (n-ma);
    }
    ans = min(res, ans);
    return;
}
void dfs(int x) {
    if(x == n)  check();
    else 
        _for(j,0,24) r[x] = j, dfs(x+1);
    return;
}
void taskla3401() {
    while(cin >> n and n) {
        col.clear();
        ans = n*6;
        _for(i,0,n) _for(j,0,6) {
            string s;
            cin >> s, m[i][j] = ID(s);
        }
        //_for(i,0,n) { _for(j,0,6) cout << "  " << m[i][j]; cout << "
"; }
        dfs(0);
        cout << ans << "
";
    } return;
}
int main() {
    ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
    taskla3401();
    return 0;
}
原文地址:https://www.cnblogs.com/163467wyj/p/13549355.html