zoukankan      html  css  js  c++  java
  • 蓝桥杯-2016CC-卡片换位

    卡片换位

    你玩过华容道的游戏吗?
    这是个类似的,但更简单的游戏。
    看下面 3 x 2 的格子

    在其中放5张牌,其中A代表关羽,B代表张飞,* 代表士兵。
    还有一个格子是空着的。

    你可以把一张牌移动到相邻的空格中去(对角不算相邻)。
    游戏的目标是:关羽和张飞交换位置,其它的牌随便在哪里都可以。

    输入格式:
    输入两行6个字符表示当前的局面

    输出格式:
    一个整数,表示最少多少步,才能把AB换位(其它牌位置随意)

    例如,输入:
    * A
    **B

    程序应该输出:
    17

    再例如,输入:
    A B
    ***

    程序应该输出:
    12


    资源约定:
    峰值内存消耗 < 256M
    CPU消耗 < 1000ms

    请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

    所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

    注意: main函数需要返回0
    注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
    注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

    提交时,注意选择所期望的编译器类型。

    思路:用pair<int, int> 来描述一个坐标,对于每个局面都只记录A,B,空格的坐标,剩下三个*不关注他们在哪,不用记录。对于每个状态转移,视为空格在移动。然后BFS。用set记录已出现过的局面;

    • 广度优先搜索
      #include "bits/stdc++.h"
      using namespace std;
      typedef long long LL;
      typedef pair<int, int> PII;
      struct node {
          // a表示A, b表示B, c表示空格 
          PII a, b, c;
          // 因为set要实现小于号所以这里随便敲个小于号。只要能实现排序就行 
          friend bool operator < (node n, node m) {
              if (n.a != m.a) {
                  return n.a < m.a;
              } else if (n.b != m.b) {
                  return n.b < m. b;
              } else {
                  return n.c < m.c;
              }
          }
      } n; 
      PII A, B;
      char mp[2][4];
      // 这里的pair表示当前局面和步数 
      queue<pair<node, int> > q;
      // 记录出现过的局面 
      set<node> st;
      void check(PII c, int step) {
          // 越界情况 
          if (c.first < 0 || c.first > 1 || c.second < 0 || c.second > 2) {
              return;
          }
          node m;
          m.c = c;
          m.a = (n.a == c) ? n.c : n.a;
          m.b = (n.b == c) ? n.c : n.b;
          // 新局面之前出现过 
          if (st.count(m)) {
              return;
          }
          st.insert(m);
          q.push({m, step + 1}); 
      }
      void BFS() {
          while (!q.empty()) {
              n = q.front().first;
              int step = q.front().second;
              q.pop();
              // 已到达目标状态 
              if (n.a == B && n.b == A) {
                  printf("%d
      ", step);
                  return;
              }
              check({n.c.first - 1, n.c.second}, step);
              check({n.c.first, n.c.second - 1}, step); 
              check({n.c.first + 1, n.c.second}, step);
              check({n.c.first, n.c.second + 1}, step);
          }
      }
      int main() {
          gets(mp[0]);
          gets(mp[1]);
          // 找到原图里A, B, 空格的位置 
          for (int i = 0; i < 2; i++) {
              for (int j = 0; j < 4; j ++) {
                  if (mp[i][j] == ' ') {
                      n.c = {i, j};
                  }
                  if (mp[i][j] == 'A') {
                      n.a = A = {i, j};
                  }
                  if (mp[i][j] == 'B') {
                      n.b = B = {i, j};
                  }
              }
          }
          q.push({n, 0});
          st.insert(n); 
          BFS();
          return 0;
      }

      这题如果会BFS还是很好想的,但是check那里想了好久。check写的好会使代码比较整洁不易错。但是没有OJ可以提交这题,所以如果代码有问题请指出。

  • 相关阅读:
    NTP on FreeBSD 12.1
    Set proxy server on FreeBSD 12.1
    win32 disk imager使用后u盘容量恢复
    How to install Google Chrome Browser on Kali Linux
    Set NTP Service and timezone on Kali Linux
    Set static IP address and DNS on FreeBSD
    github博客标题显示不了可能是标题包含 特殊符号比如 : (冒号)
    server certificate verification failed. CAfile: none CRLfile: none
    删除文件和目录(彻底的)
    如何在Curl中使用Socks5代理
  • 原文地址:https://www.cnblogs.com/Angel-Demon/p/10530859.html
Copyright © 2011-2022 走看看