卡片换位

卡片换位

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

±–±--±–+
| A | * | * |
±–±--±–+
| B | | * |
±–±--±–+

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

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

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

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

例如,输入:
* A
**B
程序应该输出:
17
再例如,输入:
A B

程序应该输出:
12

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

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

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

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

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

解析

C++题解

 #include <bits/stdc++.h>
  using namespace std;
  
 char Map[5][5];
  int x_p, y_p, x_a, y_a, x_b, y_b;
  bool vis[3][3][3][3][3][3]; // 方便检测新得到的状态之前有没有添加过 
  int u[4] = {-1, 0, 0, 1}, v[4] = {0, -1, 1, 0};
 
  struct Node { // 定义一个状态  
     int p_x, p_y; // 空格的坐标 
     int a_x, a_y; // A点坐标 
    int b_x, b_y; // B点坐标 
     int step;      // 初始状态到目前的状态所需步数 
      };
 
 void bfs() {
     queue<Node> q;
     Node Now; // 初始状态 
          Now.p_x = x_p, Now.p_y = y_p;
    Now.a_x = x_a, Now.a_y = y_a;
     Now.b_x = x_b, Now.b_y = y_b;
     Now.step = 0; // 步数为0  
     q.push(Now); // 压入队列 
     while(!q.empty()) { // 队列不为空 
         Now = q.front(); q.pop(); // 弹出队列中的第一个状态 
         //if(vis[Now.a_x][Now.a_y][Now.b_x][Now.b_y][Now.p_x][Now.p_y]) continue;
         vis[Now.a_x][Now.a_y][Now.b_x][Now.b_y][Now.p_x][Now.p_y] = true; // 这是一个新状态 标记遇到过 
         if(Now.a_x==x_b && Now.a_y==y_b && Now.b_x==x_a && Now.b_y==y_a) { // A B两点已经交换了 输出 
             printf("%d\n", Now.step);
             return ;
         }
         for(int i=0; i<4; ++i) { // 空格向四个方向走 
             int x = Now.p_x + u[i];
             int y = Now.p_y + v[i];
             if(x<0 || x>1 || y<0 || y>2) continue; // 越界 
             Node End = Now; // 空格向四个方向走后的状态 
             End.p_x = x, End.p_y = y, End.step++; // 更新空格的位置 
             if(x==Now.a_x && y==Now.a_y) // 交换的是A A的新位置就是上一个状态的空格位置 
                 End.a_x = Now.p_x, End.a_y = Now.p_y;
            if(x==Now.b_x && y==Now.b_y) // 交换的是B B的新位置就是上一个状态的空格位置 
                 End.b_x = Now.p_x, End.b_y = Now.p_y;
             if(vis[End.a_x][End.a_y][End.b_x][End.b_y][End.p_x][End.p_y]) // 这种情况添加过了 
                 continue;
             q.push(End); // 把新的情况添加进去 
         }
     }
 }
 
 int main() {
     for(int i=0; i<2; ++i) // 读入
         gets(Map[i]);
     for(int i=0; i<2; ++i)
         for(int j=0; j<3; ++j) { // 查找空格、A、B的位置 
             if(Map[i][j] == ' ')
                 x_p = i, y_p = j;
             if(Map[i][j] == 'A')
                 x_a = i, y_a = j;
             if(Map[i][j] == 'B')
                 x_b = i, y_b = j;
        }
     memset(vis, false, sizeof(vis));
     bfs();
     return 0;
 }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值