原题链接
考察:枚举
错误思路:
枚举每一面为正面,给骰子每一面编号,然后求出当前枚举骰子状况每一面为正面的情况,并用字符串记录.
错误原因:
不一定只转一次.....
思路:
参考官方题解:
- 首先先要先知道对于一个已经涂好颜色的正方体,可以有24中旋转方式:选择不同的面作为正面,故而有6种,然后保持该面为正面,可以做4次旋转(没错,就和转把手一样转),得24。
- 第二步要对每个面编号。比如正面为1,右侧为2,上为3……
- 然后我们可以暴力对一个正方体涂色得到一个字符串(以上面编号的顺序),然后再对它进行\(24\)次旋转,得到\(24\)个字符串,取字典序最小的作为当前涂的颜色的代表,存到
set
去重,最后set
的大小就是我们的答案了.
Code
#include <iostream>
#include <cstring>
#include <set>
using namespace std;
const int N = 10;
string s;
set<string> st;
int ans;
bool vis[N];
string change(int w,string s)
{
string str = "";
if(w==1) return str = s;
if(w==2)
{
str+=s[3],str+=s[2],str+=s[0];
str+=s[1],str+=s[4],str+=s[5];
}
if(w==3)
{
str+=s[4],str+=s[5],str+=s[2];
str+=s[3],str+=s[1],str+=s[0];
}
if(w==4)
{
str+=s[2],str+=s[3],str+=s[1];
str+=s[0],str+=s[4],str+=s[5];
}
if(w==5)
{
str+=s[1],str+=s[0],str+=s[3];
str+=s[2],str+=s[4],str+=s[5];
}
if(w==6)
{
str+=s[5],str+=s[4],str+=s[3];
str+=s[2],str+=s[1],str+=s[0];
}
return str;
}
string rorate(string s)
{
string str = s.substr(0,2);
str+=s[4];
str+=s[5];
str+=s[3];
str+=s[2];
return str;
}
void dfs(string str)
{
if(str.size()==6)
{
if(!st.count(str))
{
ans++;
for(int i=1;i<=6;i++)
{
string sp = change(i,str);
for(int j=1;j<=4;j++) st.insert(sp = rorate(sp));
}
}
return;
}
for(int i=0;i<s.size();i++)
{
if(vis[i]) continue;
vis[i] = 1;
dfs(str+s[i]);
vis[i] = 0;
}
}
int main()
{
cin>>s;
dfs("");
printf("%d\n",ans);
return 0;
}