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可以提交这题,所以如果代码有问题请指出。

  • 相关阅读:
    my functions.h
    MFC中GDI之CBitmap(位图)
    MFC中GDI之CFont(字体)
    MFC中GDI之CBrush(画刷)
    MFC中SDI设置状态栏显示时间
    MFC中自定义消息
    MFC常用控件类
    MFC中改变窗口大小MoveWindow...
    MFC中建立关联变量的几种方式
    软件默认端口整理
  • 原文地址:https://www.cnblogs.com/Angel-Demon/p/10530859.html
Copyright © 2011-2022 走看看