zoukankan      html  css  js  c++  java
  • HDU 1430 魔板

    思路:

    初态a和末态b经过相同的一系列操作,使初态a变成12345678,同时得到新的末态c,然后只需要求12345678到末态c的变换步骤即为初态a到末态b的变换步骤。所以,只要把12345678的所有可达状态遍历一次并记录下变换步骤即可。

     1 #include <cstdio>
     2 #include <string.h>
     3 #include <stack>
     4 using namespace std;
     5 const int MAX = 40500, fact[] = {1, 1, 2, 6, 24, 120, 720, 5040}, Move[3][8] = {{7, 6, 5, 4, 3, 2, 1, 0}, {3, 0, 1, 2, 5, 6, 7, 4}, {0, 6, 1, 3, 4, 2, 5, 7}};
     6 bool vis[MAX] = {0};
     7 int LOG[MAX][8] = {1, 2, 3, 4, 5, 6, 7, 8};
     8 struct node
     9 {
    10     char MOVE;
    11     int father;
    12 }path[MAX];
    13 bool TryToInsert(int Front, int Rear, int MOVE)
    14 {
    15     int Fcode = 0, Rcode = 0, i, j, cnt;
    16     for(i=0; i<7; ++i)
    17     {
    18         cnt = 0;
    19         for(j=i+1; j<8; ++j)
    20             if(LOG[Rear][i] > LOG[Rear][j])
    21                 ++cnt;
    22         Rcode += cnt * fact[7-i];
    23     }
    24     if(vis[Rcode])
    25         return false;
    26     else
    27     {
    28         for(i=0; i<7; ++i)
    29         {
    30             cnt = 0;
    31             for(j=i+1; j<8; ++j)
    32                 if(LOG[Front][i] > LOG[Front][j])
    33                     ++cnt;
    34             Fcode += cnt * fact[7-i];
    35         }
    36         path[Rcode].father = Fcode;
    37         path[Rcode].MOVE = 'A' + MOVE;
    38         return vis[Rcode] = true;
    39     }
    40 }
    41 void BFS(void)
    42 {
    43     vis[0] = true;
    44     int Front = 0, Rear = 1, i, j;
    45     do
    46     {
    47         for(i=0; i<3; ++i)
    48         {
    49             for(j=0; j<8; ++j)
    50                 LOG[Rear][j] = LOG[Front][ Move[i][j] ];
    51             if(TryToInsert(Front, Rear, i))
    52                 ++Rear;
    53         }
    54         ++Front;
    55     } while (Front < Rear);
    56 }
    57 int main(void)
    58 {
    59     BFS();
    60     stack<char> s;
    61     int Start[8], End[8], Aim[8], AimCode, i, j, cnt;
    62     char StartStr[10], EndStr[10];
    63     while(~scanf("%s%s", StartStr, EndStr))
    64     {
    65         for(i=0; i<8; ++i)
    66         {
    67             Start[i] = StartStr[i] - '0';
    68             End[i] = EndStr[i] - '0';
    69         }
    70         for(i=0; i<8; ++i)
    71         {
    72             for(j=0; End[i] != Start[j]; ++j);
    73             Aim[i] = j+1;
    74         }
    75         AimCode = 0;
    76         for(i=0; i<7; ++i)
    77         {
    78             cnt = 0;
    79             for(j=i+1; j<8; ++j)
    80                 if(Aim[i] > Aim[j])
    81                     ++cnt;
    82             AimCode += cnt * fact[7-i];
    83         }
    84         while(AimCode)
    85         {
    86             s.push(path[AimCode].MOVE);
    87             AimCode = path[AimCode].father;
    88         }
    89         while(!s.empty())
    90         {
    91             printf("%c", s.top());
    92             s.pop();
    93         }
    94         printf("
    ");
    95     }
    96 }
  • 相关阅读:
    线段树练习两题
    DP+单调队列 codevs 1748 瑰丽华尔兹(还不是很懂具体的代码实现)
    线段树和树状数组问题补充
    一些常见的优化:读入优化,滚动数组
    单调队列应用--BZOJ 3831 Little Bird
    单调队列练习之广告印刷
    详解--单调队列 经典滑动窗口问题
    数据结构--栈 codevs 1107 等价表达式
    离散化+线段树 POJ 3277 City Horizon
    求次短路 codevs 1269 匈牙利游戏
  • 原文地址:https://www.cnblogs.com/corvey/p/4779350.html
Copyright © 2011-2022 走看看