HDU4801·二阶魔方

题意:给定二阶魔方初始状态,问N(1 <= N <= 7)步旋转操作以内最多能使几个面相同。

 

dfs搜索+剪枝。

魔方的每个旋转操作即对应于一个置换操作。又因为相对运动,上层左旋一次和下层右旋一次等价,故可分为6类操作。上层顺、逆时针旋转,左层顺、逆时针旋转,前层顺、逆时针旋转。这样每次操作有6种选择。

剪枝一:考虑旋转操作一次后,第二次不应进行逆操作回到旋转前状态。实现的时候将每种操作分别置为0、 1, 2、 3, 4、 5,操作1^操作2 = 1则说明两操作互为逆操作。

剪枝二:当有6个面相同时就停止搜索。

剪枝三:每个操作最多连续操作2次。(下述代码未实现该剪枝)

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int a[8][24], ans, n;
 4 int turn[6][24] = {
 5     {0,1,8,14,4,3,7,13,17,9,10,2,6,12,16,15,5,11,18,19,20,21,22,23},
 6     {0,1,11,5,4,16,12,6,2,9,10,17,13,7,3,15,14,8,18,19,20,21,22,23},
 7 
 8     {1,3,0,2,23,22,4,5,6,7,10,11,12,13,14,15,16,17,18,19,20,21,9,8},
 9     {2,0,3,1,6,7,8,9,23,22,10,11,12,13,14,15,16,17,18,19,20,21,5,4},
10 
11     {6,1,12,3,5,11,16,7,8,9,4,10,18,13,14,15,20,17,22,19,0,21,2,23},
12     {20,1,22,3,10,4,0,7,8,9,11,5,2,13,14,15,6,17,12,19,16,21,18,23},
13 };
14 void debug(int a[], int p, int t){
15     if(t == 0) return ;
16     int b[24];
17     for(int i = 0; i < 24; i++){
18         b[i] = a[ turn[p][i] ];
19         printf("%d ", b[i]);
20     }
21     puts("");
22 
23     debug(b, p, t-1);
24 }
25 void dfs(int d, int pre){
26     if(ans >= 6||d > n) return ;
27     if(d) for(int j = 0; j < 24; j++)
28             a[d][j] = a[d-1][ turn[pre][j] ];
29     int now = (a[d][0]  ==  a[d][1]&&a[d][1]  ==  a[d][2]&&a[d][2]  == a[d][3]) +
30               (a[d][4]  ==  a[d][5]&&a[d][5]  == a[d][10]&&a[d][10] == a[d][11])+
31               (a[d][6]  ==  a[d][7]&&a[d][7]  == a[d][12]&&a[d][12] == a[d][13])+
32               (a[d][8]  ==  a[d][9]&&a[d][9]  == a[d][14]&&a[d][14] == a[d][15])+
33               (a[d][16] == a[d][17]&&a[d][17] == a[d][18]&&a[d][18] == a[d][19])+
34               (a[d][20] == a[d][21]&&a[d][21] == a[d][22]&&a[d][22] == a[d][23]);
35     ans = max(ans, now);
36     for(int i = 0; i < 6; i++)
37         if( (i^pre) != 1) dfs(d+1, i);
38 }
39 int main(){
40     while(~scanf("%d", &n)){
41         for(int i = 0; i < 24; i++)
42             scanf("%d", &a[0][i]);
43         ans = 0;
44         dfs(0, -1);
45         cout<<ans<<endl;
46     }
47     return 0;
48 }
View Code

 

posted @ 2016-02-23 13:30  我在地狱  阅读(582)  评论(1编辑  收藏  举报