zoukankan      html  css  js  c++  java
  • 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
    诸神对凡人心生艳羡,厌倦天堂。
  • 相关阅读:
    Linux下Mysql的安装步骤
    分布式集群Session原理及实现共享
    MySQL数据库表分区功能详解
    PHP面向对象程序设计之接口(interface)
    PHP面向对象程序设计之抽象类和抽象方法
    MySQL优化技巧
    MySQL性能优化之max_connections参数
    PHP环境下Memcache的使用方法
    PHP之Trait详解
    如何选择合适的MySQL数据类型
  • 原文地址:https://www.cnblogs.com/dirge/p/5209603.html
Copyright © 2011-2022 走看看