uva 1352(暴力)

题意:有n个正方体上任意涂了一些颜色,现在要改变一些正方体上的一些面上的颜色使n个正方体在某种旋转情况下可以对应面颜色相同,问最少改变多少个面的颜色。

题解:因为最多4个正方体,暴力可行,然后就是考虑24种旋转方式(当两个方向面确定,一个正方体就确定),先让一个正方体确定,根据每种旋转方式改变其它正方体的面,选出改变面的数量最少的。


#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <map>
using namespace std;
map<string, int> m;
int n, pose[30][6], r[5], color[5][6], cube[5][6], res;
int Left[6] = {4, 0, 2, 3, 5, 1};
int up[6] = {2, 1, 5, 0, 4, 3};

void rot(int* ch, int* p) {
	int q[6];	
	for (int i = 0; i < 6; i++)
		q[i] = p[i];
	for (int i = 0; i < 6; i++)
		p[i] = ch[q[i]];
}

void get_pose() {
	int p0[6] = {0, 1, 2, 3, 4, 5}, Count = 0;
	for (int i = 0; i < 6; i++)	{
		int p[6];
		for (int j = 0; j < 6; j++)
			p[j] = p0[j];
		switch(i) {
			case 0: rot(up, p); break;
			case 1: rot(Left, p); rot(up, p); break;
			case 2: break;
			case 3: rot(up, p); rot(up, p); break;
			case 4: rot(Left, p); rot(Left, p); rot(Left, p); rot(up, p); break;
			case 5: rot(Left, p); rot(Left, p); rot(up, p);	break;
		}
		for (int j = 0; j < 4; j++) {
			for (int k = 0; k < 6; k++)
				pose[Count][k] = p[k];
			Count++;
			rot(Left, p);
		}
	}
}

void judge() {
	for (int i = 0; i < n; i++)
		for (int j = 0; j < 6; j++)
			color[i][pose[r[i]][j]] = cube[i][j];
	int temp = 0, cnt[30];
	for (int j = 0; j < 6; j++) {
		memset(cnt, 0, sizeof(cnt));
		int maxface = 0;
		for (int i = 0; i < n; i++)
			maxface = max(maxface, ++cnt[color[i][j]]);
		temp += n - maxface;
	}
	res = min(temp, res);
}

void dfs(int cur) {
	if (cur == n)
		judge();
	else
		for (int i = 0; i < 24; i++) {
			r[cur] = i;
			dfs(cur + 1);
		}
}

int main() {
	get_pose();
	while (scanf("%d", &n) && n) {
		string c;
		int k = 0;
		m.clear();
		for (int i = 0; i < n; i++)
			for (int j = 0; j < 6; j++) {
				cin >> c;
				if (m[c])
					cube[i][j] = m[c];
				else
					m[c] = cube[i][j] = ++k;
			}
		res = n * 6;
		r[0] = 0;
		dfs(1);
		printf("%d\n", res);
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值