Colored Cubes UVA - 1352
题意:
有n个带颜色的立方体,你可以任意旋转,之后涂最少的颜色,使得所有正方体相同。
思路:
- 第一个不动,其他旋转(一个正方体总共24种姿态)
- 之后写dfs并check’
- 先打表,打出排列
AC
#include <iostream>
#include <bits/stdc++.h>
#define For(i,x,y) for(int i=(x); i<=(y); i++)
#define fori(i,x,y) for(int i=(x); i<(y); i++)
#define rep(i,y,x) for(int i=(y); i>=(x); i--)
#define mst(x,a) memset(x,a,sizeof(x))
#define pb push_back
#define sz(a) (int)a.size()
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int>pa;
typedef pair<ll,ll>pai;
int up[]={2,1,5,0,4,3};
int lef[]={4,0,2,3,5,1};
///p[i] represent the position of idex of i.
///0 formal 1 right 2 up 3 bottom 4 left 5 back
void rot(int* T ,int *P){
int q[6];
memcpy(q,P,sizeof(q));
fori(i,0,6)P[i] = T[q[i]];
}
void enumerate_permutations(){
int p0[6] = {0,1,2,3,4,5};
printf("int dice24[24][6] = {\n");
fori(i,0,6){
int p[6];
memcpy(p,p0,sizeof(p0));
if(i==0)rot(up,p);
if(i==1)rot(lef,p),rot(up,p);
if(i==3)rot(up,p),rot(up,p);
if(i==4)rot(lef,p),rot(lef,p),rot(lef,p),rot(up,p);
if(i==5)rot(lef,p),rot(lef,p),rot(up,p);
fori(j,0,4){
printf("{%d,%d,%d,%d,%d,%d},",p[0],p[1],p[2],p[3],p[4],p[5]);
rot(lef,p);
}
printf("\n");
}
printf("};\n");
}
int dice24[24][6] = {
{2,1,5,0,4,3},{2,0,1,4,5,3},{2,4,0,5,1,3},{2,5,4,1,0,3},
{4,2,5,0,3,1},{5,2,1,4,3,0},{1,2,0,5,3,4},{0,2,4,1,3,5},
{0,1,2,3,4,5},{4,0,2,3,5,1},{5,4,2,3,1,0},{1,5,2,3,0,4},
{5,1,3,2,4,0},{1,0,3,2,5,4},{0,4,3,2,1,5},{4,5,3,2,0,1},
{1,3,5,0,2,4},{0,3,1,4,2,5},{4,3,0,5,2,1},{5,3,4,1,2,0},
{3,4,5,0,1,2},{3,5,1,4,0,2},{3,1,0,5,4,2},{3,0,4,1,5,2},
};
int dice[4][6];
int n;
map<string,int>id;
vector<string>v;
int idc(char * x){
string s(x);
if(id.count(s))return id[s];
v.pb(s);
return id[s]=sz(v)-1;
}
int ans;
int r[5];
void check(){
int res = 0;
fori(i,0,6){
int mx = 0, mx_col;
int cnt[26]{};
fori(k,0,n){
int idx = dice24[r[k]][i];
cnt[dice[k][idx]]++;
if(mx < cnt[dice[k][idx]])mx = cnt[dice[k][idx]];
}
res += n-mx;
}
ans = min(ans,res);
}
void dfs(int s){
if(s==n){
check();
return ;
}
fori(i,0,24)r[s]=i,dfs(s+1);
}
int main()
{
// ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
// enumerate_permutations();
while(scanf("%d", &n)&&n){
id.clear(); v.clear();
char col[30];
fori(i,0,n)fori(j,0,6)scanf("%s", col),dice[i][j] = idc(col);
ans = n*6;
r[0] = 0;
dfs(1);
printf("%d\n", ans);//cout<<ans<<'\n';
}
return 0;
}
本文分享了如何通过旋转立方体和深度优先搜索策略,找出最少颜色涂装所有立方体的方法。通过列举所有可能的正方体姿态,并进行遍历,找到使所有立方体颜色相同的最省方案。

465

被折叠的 条评论
为什么被折叠?



