UVALive 3401

题目

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1402


题意

4个方块,每个方块每个面涂不同的颜色,问最少重涂多少面,使四个方块相同。

思路

如刘书思路,明显,方块是可以旋转的。旋转的方式不可能多。旋转的基本操作可以定为右旋和上旋,其他所有旋转都是这两种子操作的集合。

通过搜索确定所有可能的旋转方式后,接下来就是确定该如何涂色。

选定第一个方块作为参考系,对剩下的方块分别尝试一下可能的旋转方式。确定旋转方式后,答案就很简单的相加即得。

感想

1. 三倍ice cream!

代码

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <tuple>
#include <set>
#include <map>
#include <cassert>
#define LOCAL_DEBUG
using namespace std;
const int MAXN = 5;
int rightPositions[6] = { 4, 0, 2, 3, 5, 1 };
int topPositions[6] = { 3, 1, 0, 5, 4, 2 };
int n;

class Status {
public:
    int faces[6];
    Status() {
        for (int i = 0; i < 6; i++) {
            faces[i] = i;
        }
    }
    Status(int _faces[6]) {
        for (int i = 0; i < 6; i++) {
            faces[i] = _faces[i];
        }
    }

    bool operator ==(const Status & other)const {
        for (int i = 0; i < 6; i++) {
            if (faces[i] != other.faces[i])return false;
        }
        return true;
    }

    bool operator <(const Status & other)const {
        for (int i = 0; i < 6; i++) {
            if (faces[i] < other.faces[i])return true;
            else if (faces[i] > other.faces[i])return false;
        }
        return false;
    }

    void rotate(int positions[6]) {
        int tmp[6];
        for (int i = 0; i < 6; i++) {
            tmp[i] = faces[i];
        }
        for (int i = 0; i < 6; i++) {
            faces[i] = tmp[positions[i]];
        }
    }

    void reRotate(int positions[6]) {
        int tmp[6];
        for (int i = 0; i < 6; i++) {
            tmp[i] = faces[i];
        }
        for (int i = 0; i < 6; i++) {
            faces[positions[i]] = tmp[i];
        }
    }


    Status copy() {
        Status newStatus;
        for (int i = 0; i < 6; i++) {
            newStatus.faces[i] = faces[i];
        }
        return newStatus;
    }
};

set<Status> statuses;

void buildStatus() {
    queue<Status> que;
    Status status;
    que.push(status);
    statuses.insert(status);
    while (!que.empty()) {
        status = que.front(); que.pop();
        Status newStatus = status.copy();
        newStatus.rotate(rightPositions);
        if (statuses.count(newStatus) == 0) {
            que.push(newStatus);
            statuses.insert(newStatus);
        }
        newStatus = status.copy();
        newStatus.rotate(topPositions);
        if (statuses.count(newStatus) == 0) {
            que.push(newStatus);
            statuses.insert(newStatus);
        }
    }
}

Status cubes[MAXN];
int cnt[MAXN * 6];

int dfs(int id) {
    int ans = 6 * MAXN;
    if (id < n) {
        for (auto status : statuses) {
            cubes[id].rotate(status.faces);
            ans = min(dfs(id + 1), ans);
            cubes[id].reRotate(status.faces);
        }
    }
    else {
        ans = 0;
        for (int j = 0; j < 6; j++) {
            for (int i = 0; i < n; i++) {
                cnt[cubes[i].faces[j]] ++;
            }
            int best_color = 0;
            for (int i = 0; i < MAXN * 6; i++) {
                if (cnt[i] > cnt[best_color]) {
                    best_color = i;
                }
            }
            ans += n - cnt[best_color];
            memset(cnt, 0, sizeof(cnt));
        }
    }
    return ans;
}

int main() {
#ifdef LOCAL_DEBUG
    freopen("input.txt", "r", stdin);
    //freopen("output2.txt", "w", stdout);
#endif // LOCAL_DEBUG
    buildStatus();
    for (int ti = 1; scanf("%d", &n) == 1 && n; ti++) {
        map<string, int> colorNameMap;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < 6; j++) {
                char tmp[25];
                scanf("%s", tmp);
                string colorName = tmp;
                if (colorNameMap.count(colorName) == 0) {
                    colorNameMap[colorName] = colorNameMap.size();
                }
                cubes[i].faces[j] = colorNameMap[colorName];
            }
        }
        int ans = dfs(1);
        printf("%d
", ans);
    }

    return 0;
}
View Code
原文地址:https://www.cnblogs.com/xuesu/p/10365519.html