zoukankan      html  css  js  c++  java
  • 【广搜】棋盘游戏

    题目描述

    在一个4*4的棋盘上有8个黑棋和8个白棋,当且仅当两个格子有公共边,这两个格子上的棋是相邻的。移动棋子的规则是交换相邻两个棋子。现在给出一个初始棋盘和一个最终棋盘,要求你找出一个最短的移动序列使初始棋盘变为最终棋盘。
    Klux说:“这么简单的题目,我都会做!”

    输入

    第1到4行每行四个数字(1或者0),描述了初始棋盘。
    接着是一个空行。
    第6到9行每行四个数字,描述了最终棋盘。

    输出

    第一行是一个整数n,表示最少的移动步数。
    接下来n行每行4个数,r1,c1,r2,c2,表示移动的两个棋子的坐标(r1,c1),(r2,c2)(棋盘左上角的坐标为(1,1),并且他右边的格子为(1,2))
    如果有许多组解,你可以输出任意一组。

    样例输入

    1111
    0000
    1110
    0010
    
    1010
    0101
    1010
    0101
    

    样例输出

    4
    1 2 2 2
    1 4 2 4
    3 2 4 2
    4 3 4 4




    【题意】

      交换即可,但是大家要这个状态不好标记处理,所以我们需要hash处理,这个01矩阵,不难想到我们处理成二进制来处理。

      我们怎么处理这个题目中1,0对应的位置呢???我们可以用我们二维数组通用的hash方法,就是除以列宽得行号,对列宽取余得到列号的做法。

      ”交换“:如何实现??

      同样地得到上下两个坐标的位置,同时其实他们对应的二进制也是序号来记录的,然后我们直接找到两个位置,用异或处理就可以交换0和1的操作。

      怎么打印这个答案呢??

      我认为这个题目还有一点就是记录路径的方法,记录路径是非常考验人的,但是我们需要开一个结构体,

      这个结构体需要记录这次hash值对应的哪两个坐标进行交换了,同时这个结构体能通过最终状态的hash值回溯输出。

    【代码】:

      

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N = (1<<16)+10;
     4 int pre[N],vis[N];
     5 typedef struct Node {
     6     int x,y,px,py ;
     7     int pre_Num ;
     8 }Node ;
     9 Node ans[N];
    10 int n,m;
    11 void dfs(int No){
    12     if( ans[No].pre_Num != n )
    13         dfs(ans[No].pre_Num);
    14     printf("%d %d %d %d
    ",ans[No].x,ans[No].y,ans[No].px,ans[No].py);
    15 }
    16 void BFS(){
    17     queue < int > Q ;
    18     Q.push ( n );
    19     while ( !Q.empty() ) {
    20         int cur = Q.front();
    21         Q.pop();
    22         // 上下互换
    23         for(int i=0;i<=11;i++){
    24             int u = ( cur & (1<<i) ) >> i ;
    25             int v = ( cur & (1<<i+4) ) >> (i+4);
    26             int tmp = ( 1<<(i+4) ) + (1<<i) ;
    27             if ( u != v ){
    28                 int next = cur ^ tmp ;
    29                 if( vis[next] == 0 ){
    30                     ans[next].x = i / 4 + 1 ;
    31                     ans[next].px = ans[next].x + 1 ;
    32                     ans[next].y = ans[next].py = i % 4 + 1 ;
    33                     ans[next].pre_Num = cur ;
    34                     vis[next] = vis[cur] + 1 ;
    35                     Q.push(next);
    36                     if ( next == m ){
    37                         printf("%d
    ",vis[m]);
    38                         dfs(next);
    39                         return ;
    40                     }
    41                 }
    42             }
    43         }
    44         // 左右互换
    45         for(int i=0;i<=15;i++){
    46             if(i%4==3) continue ;
    47             int u = ( cur & (1<<i) ) >> i ;
    48             int v = ( cur & (1<<(i+1)) ) >> (i+1);
    49             int tmp = ( 1<<(i+1) ) + (1<<i) ;
    50             if ( u != v ){
    51                 int next = cur ^ tmp ;
    52                 if( vis[next] == 0 ){
    53                     ans[next].px = ans[next].x = i / 4 + 1 ;
    54                     ans[next].y =  i % 4 + 1 ;
    55                     ans[next].py = i % 4 + 2 ;
    56                     ans[next].pre_Num = cur ;
    57                     vis[next] = vis[cur] + 1 ;
    58                     Q.push(next);
    59                     if ( next == m ){
    60                         printf("%d
    ",vis[m]);
    61                         dfs(next);
    62                         return ;
    63                     }
    64                 }
    65             }
    66         }
    67     }
    68 }
    69 int main()
    70 {
    71     for(int i=0,x;i<16;i++){
    72         scanf("%1d",&x);
    73         n += x * (1<<i);
    74     }
    75     for(int i=0,x;i<16;i++){
    76         scanf("%1d",&x);
    77         m += x * (1<<i);
    78     }
    79     if ( n==m ){
    80         return 0*puts("0");
    81     }else{
    82         BFS();
    83     }
    84     return 0;
    85 }
    86 
    87 /*
    88 
    89 1111
    90 0000
    91 1110
    92 0010
    93 
    94 1010
    95 0101
    96 1010
    97 0101
    98 
    99 */
    棋盘游戏
  • 相关阅读:
    控制反转(IOC)/依赖注入(DI)理解
    MySQL常用命令总结
    Java继承与清理
    Java组合与继承生成的类中构造函数的执行顺序
    Java中4种权限的理解
    C# 选项卡控件
    USMART 组件移植到STM32
    c# 规范用户输入控件
    c# 图像呈现控件PictureBox
    C# 制作软件启动界面
  • 原文地址:https://www.cnblogs.com/Osea/p/11215746.html
Copyright © 2011-2022 走看看