本题的关键是生成一个Cubes合法的24种姿态。
生成方法就是将每一个面当做顶面一次,然后左旋三次,这样每一个顶面可以得到4个姿态,最后一共得到 6*4=24中姿态
然后利用生成的序列进行枚举,但是这里有一个技巧就是 我们可以固定一个Cubes不旋转,而剩余的(n-1)个Cubes我们来枚举他们处于的姿态。
这样就将时间复杂度从 24^n 减少到 24^(n-1)
另外注意点就是少用string 和 map 最初TLE到最后150ms效率可见一斑。
Colored Cubes
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 622 | Accepted: 334 |
Description
There are several colored cubes. All of them are of the same size but they may be colored differently. Each face of these cubes has a single color. Colors of distinct faces of a cube may or may not be the same.
Two cubes are said to be identically colored if some suitable rotations of one of the cubes give identical looks to both of the cubes. For example, two cubes shown in Figure 2 are identically colored. A set of cubes is said to be identically colored if every pair of them are identically colored.
A cube and its mirror image are not necessarily identically colored. For example, two cubes shown in Figure 3 are not identically colored.
You can make a given set of cubes identically colored by repainting some of the faces, whatever colors the faces may have. In Figure 4, repainting four faces makes the three cubes identically colored and repainting fewer faces will never do.
Your task is to write a program to calculate the minimum number of faces that needs to be repainted for a given set of cubes to become identically colored.
Two cubes are said to be identically colored if some suitable rotations of one of the cubes give identical looks to both of the cubes. For example, two cubes shown in Figure 2 are identically colored. A set of cubes is said to be identically colored if every pair of them are identically colored.
A cube and its mirror image are not necessarily identically colored. For example, two cubes shown in Figure 3 are not identically colored.
You can make a given set of cubes identically colored by repainting some of the faces, whatever colors the faces may have. In Figure 4, repainting four faces makes the three cubes identically colored and repainting fewer faces will never do.
Your task is to write a program to calculate the minimum number of faces that needs to be repainted for a given set of cubes to become identically colored.
Input
The input is a sequence of datasets. A dataset consists of a header and a body appearing in this order. A header is a line containing one positive integer n and the body following it consists of n lines. You can assume that 1 <= n <= 4. Each line in a body contains six color names separated by a space. A color name consists of a word or words connected with a hyphen (-). A word consists of one or more lowercase letters. You can assume that a color name is at most 24-characters long including hyphens.
A dataset corresponds to a set of colored cubes. The integer n corresponds to the number of cubes. Each line of the body corresponds to a cube and describes the colors of its faces. Color names in a line is ordered in accordance with the numbering of faces shown in Figure 5. A line
corresponds to a cube colored as shown in Figure 6.
The end of the input is indicated by a line containing a single zero. It is not a dataset nor a part of a dataset.
A dataset corresponds to a set of colored cubes. The integer n corresponds to the number of cubes. Each line of the body corresponds to a cube and describes the colors of its faces. Color names in a line is ordered in accordance with the numbering of faces shown in Figure 5. A line
- color1 color2 color3 color4 color5 color6
corresponds to a cube colored as shown in Figure 6.
The end of the input is indicated by a line containing a single zero. It is not a dataset nor a part of a dataset.



Output
For each dataset, output a line containing the minimum number of faces that need to be repainted to make the set of cubes identically colored.
Sample Input
3 scarlet green blue yellow magenta cyan blue pink green magenta cyan lemon purple red blue yellow cyan green 2 red green blue yellow magenta cyan cyan green blue yellow magenta red 2 red green gray gray magenta cyan cyan green gray gray magenta red 2 red green blue yellow magenta cyan magenta red blue yellow cyan green 3 red green blue yellow magenta cyan cyan green blue yellow magenta red magenta red blue yellow cyan green 3 blue green green green green blue green blue blue green green green green green green green green sea-green 3 red yellow red yellow red yellow red red yellow yellow red yellow red red red red red red 4 violet violet salmon salmon salmon salmon violet salmon salmon salmon salmon violet violet violet salmon salmon violet violet violet violet violet violet salmon salmon 1 red green blue yellow magenta cyan 4 magenta pink red scarlet vermilion wine-red aquamarine blue cyan indigo sky-blue turquoise-blue blond cream chrome-yellow lemon olive yellow chrome-green emerald-green green olive vilidian sky-blue 0
Sample Output
4 2 0 0 2 3 4 4 0 16
Source
AC代码
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<map>
#include<iterator>
#include<cstdio>
#include<vector>
using namespace std;
int n;
int cube[][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}};
map<string,int> msi;
int p;
int ans;
int selects[6];
int color[7][7];
int dice[7][7];
int counts[60];
void dfs(int sel){
if(sel==n-1){
for(int i=1;i<n;i++){
int st=selects[i-1];
for(int j=0;j<6;j++)
color[i][cube[st][j]]=dice[i][j];
}
int ret=0,cnt;
for(int i=0;i<6;i++){
memset(counts,0,sizeof(counts));
counts[dice[0][i]]++;cnt=1;
for(int j=0;j<n-1;j++)
cnt=max(cnt,++counts[color[j+1][i]]);
ret+=(n-cnt);
}
ans=min(ans,ret);
}
else{
for(int i=0;i<24;i++){
selects[sel]=i;
dfs(sel+1);
}
}
}
char colors[100];
int main(){
while(~scanf("%d",&n)){
if(!n) break;
p=0;msi.clear();
for(int i=0;i<n;i++){
for(int j=0;j<6;j++){
scanf("%s",colors);
if(msi.count(colors)==0)
msi[colors]=p++;
dice[i][j]=msi[colors];
}
}
ans=(n-1)*6;
dfs(0);
printf("%d\n",ans);
}
return 0;
}
枚举产生序列的代码
#include<iostream>
#include<fstream>
#include<cstdlib>
#include<cstring>
#include<string>
using namespace std;
//两种旋转策略
int le[6]={4,0,2,3,5,1};
int up[6]={2,1,5,0,4,3};
void rot(int* t,int* p){
int q[6];
memcpy(q,p,sizeof(q));
for(int i=0;i<6;i++)
p[i]=t[q[i]];
}
void print(ofstream & s,int *p){
s<<"{"<<p[0]<<","<<p[1]<<","<<p[2]
<<","<<p[3]<<","<<p[4]<<","<<p[5]<<"},"<<endl;
}
//按照每次最上方的数字序列为1,2,3,4,5,6次序进行旋转求出24个序列
int main(){
ofstream myfile("out.txt");
int ori[]={0,1,2,3,4,5};
int p[6];
for(int i=0;i<6;i++){
memcpy(p,ori,sizeof(p));
if(i==0) rot(up,p);
if(i==1){
rot(le,p);
rot(up,p);
}
if(i==3){
rot(up,p);
rot(up,p);
}
if(i==4){
rot(le,p);
rot(le,p);
rot(le,p);
rot(up,p);
}
if(i==5){
rot(le,p);
rot(le,p);
rot(up,p);
}
for(int i=0;i<4;i++){
print(myfile,p);
rot(le,p);
}
}
return 0;
}