UVALive 3401 Colored Cubes

刘汝佳大神书上的题目,每一个方框有24中不同的姿态,第一个方块的姿态不变,然后去枚举后面的几个方块的姿态,最佳的涂色方案必然是各个方块处于一个固定的姿态然后进行涂色,在几个方块的姿态在枚举中都固定之后,当前这种姿态的排列方式中,最少的涂色方式应该是先统计几个方块的某个同一个面的颜色是什么,其中把颜色最多的一种颜色选为标准的颜色,把这几个方块的这个面都涂成这个颜色,那么对应的涂色次数自然就最小的,枚举所有姿态的组合,不停更新最小的涂色总次数就行了,书上说得不是很清楚,想了半天才想通原来书上说得是这个意思。

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <set>
#include <map>

#define		INF			0x3fffffff
using namespace std;

string cube[4][6];
string cube_try[4][6];
set<string> all_colors;
int n, min_sum;

int format[24][6] = {
	{0, 1, 2, 3, 4, 5},
	{4, 0, 2, 3, 5, 1},
	{5, 4, 2, 3, 1, 0},
	{1, 5, 2, 3, 0, 4},

	{3, 1, 0, 5, 4, 2},
	{4, 3, 0, 5, 2, 1},
	{2, 4, 0, 5, 1, 3},
	{1, 2, 0, 5, 3, 4},

	{0, 3, 1, 4, 2, 5},
	{2, 0, 1, 4, 5, 3},
	{5, 2, 1, 4, 3, 0},
	{3, 5, 1, 4, 0, 2},

	{0, 2, 4, 1, 3, 5},
	{3, 0, 4, 1, 5, 2},
	{5, 3, 4, 1, 2, 0},
	{2, 5, 4, 1, 0, 3},

	{0, 4, 3, 2, 1, 5},
	{1, 0, 3, 2, 5, 4},
	{5, 1, 3, 2, 4, 0},
	{4, 5, 3, 2, 0, 1},

	{1, 3, 5, 0, 2, 4},
	{2, 1, 5, 0, 4, 3},
	{4, 2, 5, 0, 3, 1},
	{3, 4, 5, 0, 1, 2}
};

void change_cube(string *source, string* des, int format_index){
	int i;
	for(i=0; i<6; i++){
		des[i] = source[format[format_index][i]];
	}
}

void dfs(int cur){
	int i, j, k, max, count;
	string color;
	map<string, int> m;

	if(0 == cur){
		for(i=0; i<6; i++) cube_try[0][i] = cube[0][i];
		dfs(cur+1);
		return;
	}
	else{
		for(i=0; i<24;i++){
			change_cube(cube[cur], cube_try[cur], i);
			if(cur <= n-2)
				dfs(cur+1);
			else{
				count = 0;
				for(k=0; k<6; k++){
					m.clear();
					max = 0;
					for(j=0; j<n; j++){
						color = cube_try[j][k];
						if(m.find(color) == m.end())
							m[color] = 1;
						else
							m[color]++;
						if(m[color] > max)
							max = m[color];
					}
					count += n-max;
				}
				if(count < min_sum)
					min_sum = count;
			}
		}
	}

}

void func(int n){
	if(1 == n){
		printf("0\n");
		return;
	}


	min_sum = INF;
	dfs(0);
	printf("%d\n", min_sum);
}

int main(void){
	char buf[20];
	string color;
	int i, j;

	//freopen("input.dat", "r", stdin);
	all_colors.clear();
	while(scanf("%d", &n), n){
		for(i=0; i<n; i++){
			for(j=0; j<6; j++){
				scanf("%s", buf);
				color.assign(buf);
				cube[i][j] = color;
				all_colors.insert(color);
			}
		}
		func(n);
	}

	return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值