题目链接:http://codeforces.com/contest/98/problem/A
题意大意:给你6种颜色,这6种颜色可能相同也可能不同,把这几种颜色全涂在一个正方体表面,问有多少种涂法(翻转后相同算作一种)。
思路:开始枚举全排列枚举所有情况,然后dfs,发现搜出来答案少了,最后发现少考虑了情况,只考虑了固定原始上表面然后顺时针旋转和另外五个面向上翻转,没有考虑另外五个面向上翻转后顺时针转动的情况。。
正解:先固定正方体,全排列枚举所有涂的情况,进行标记,然后再对枚举的每一种情况进行处理标记,翻转了和不翻转考虑为一种,枚举的每一种情况都有24种翻转情况,都要考虑清楚,如何枚举?先固定上下表面,朝一个方向转动,有4种,有6个面可以固定在上面,总共有4*6=24种。全排列开始我用6个for循环,太笨了,可以排序后调用函数,嘎嘎。

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <map> 5 #include <algorithm> 6 using namespace std; 7 8 int pp[24][6]= 9 { 10 0,1,2,3,4,5, 11 0,2,3,4,1,5, 12 0,3,4,1,2,5, 13 0,4,1,2,3,5, 14 1,0,4,5,2,3, 15 1,4,5,2,0,3, 16 1,5,2,0,4,3, 17 1,2,0,4,5,3, 18 2,0,1,5,3,4, 19 2,1,5,3,0,4, 20 2,5,3,0,1,4, 21 2,3,0,1,5,4, 22 3,0,2,5,4,1, 23 3,2,5,4,0,1, 24 3,5,4,0,2,1, 25 3,4,0,2,5,1, 26 4,0,3,5,1,2, 27 4,3,5,1,0,2, 28 4,5,1,0,3,2, 29 4,1,0,3,5,2, 30 5,2,1,4,3,0, 31 5,1,4,3,2,0, 32 5,4,3,2,1,0, 33 5,3,2,1,4,0 34 }; 35 36 int main() 37 { 38 string s; 39 while(cin >> s) 40 { 41 map<string,int>mp; 42 sort(s.begin(),s.end()); 43 int ans=0; 44 do 45 { 46 if(!mp[s]) 47 { 48 mp[s]=1; 49 ans++; 50 for(int i=0; i<36; i++) 51 { 52 string ss=""; 53 for(int j=0; j<6; j++) ss+=s[ pp[i][j] ]; 54 mp[ss]=1; 55 } 56 } 57 }while(next_permutation(s.begin(),s.end())); ///用这个必须先排序 58 cout <<ans <<endl; 59 } 60 }