• HihoCoder1654: XY游戏([Offer收割]编程练习赛39)(好久没写搜索)(已经超级简短了)


    描述

    如下图所示,在4x4的棋盘上有X和Y两种棋子各若干枚;O表示空格。

    OXXY

    YOOX

    XOOY

    XOXX

    小Hi每次可以选择任意一枚棋子,将它移动到上下左右相邻的空格中。  

    小Hi想知道最少移动多少次可以达到胜利局面:有4个X或者4个Y连成一行、一列或者对角线(两条对角线都算胜利)。

    输入

    4x4的棋盘

    输出

    达成胜利最少需要的步数。如果小Hi无论如何也达不到胜利局面,输出-1。

    样例输入

    OXXY  
    YOOX  
    XOOY  
    XOXX

    样例输出

    思路:

    数据小,达到目标的最小步骤问题,多半是搜索。但是X,Y两个形态,那么状态压缩的话,假设0是O,1是X,2是Y,则有3^16=43046721,无法二进制处理,直接用map记录string。

     数组记录关系,好简短啊。。。

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<map>
    #include<queue>
    using namespace std;
    map<string,int>mp;
    queue<string>q;
    int head,tail;
    int a[5][5]={ {0}, {0,1,2,3}, {0,4,8,12},{0},       {3}           };
    int b[5][5]={ {0}, {4,8,12},  {1,2,3},   {5,10,15}, {3,6,9}       };
    int c[5][5]={ {0}, {3,7,11,15},{0,4,8,12},{12,13,14,15},{0,1,2,3} };
    int d[5]={0,1,-1,4,-4};
    using namespace std;
    bool check(string s)
    {
         for(int i=1;i<=2;i++)//1是列,2是行 ,a代表起始,b代表跨度。 
           for(int j=0;j<4;j++)//每行或者每列共4个 
             if(s[a[i][j]]!='O'&&s[a[i][j]]==s[a[i][j]+b[i][0]]&&s[a[i][j]]==s[a[i][j]+b[i][1]]&&s[a[i][j]]==s[a[i][j]+b[i][2]]) return true;
         for(int i=3;i<=4;i++)//对角线 
             if(s[a[i][0]]!='O'&&s[a[i][0]]==s[a[i][0]+b[i][0]]&&s[a[i][0]]==s[a[i][0]+b[i][1]]&&s[a[i][0]]==s[a[i][0]+b[i][2]]) return true;
         return false; 
    }
    int bfs()
    {
        string s,tmp;
        while(!q.empty()){
            s=q.front();q.pop();
            if(check(s)) return mp[s]-1;
            for(int pos=0;pos<16;pos++)
              for(int j=1;j<=4;j++){
                string tmp=s;
                if(pos==c[j][0]||pos==c[j][1]||pos==c[j][2]||pos==c[j][3]) continue;
                if(s[pos+d[j]]=='O'&&s[pos]!='O') {
                    tmp=s;tmp[pos]=s[pos+d[j]];tmp[pos+d[j]]=s[pos]; 
                    if(!mp[tmp]) q.push(tmp),mp[tmp]=mp[s]+1;
                }
            }
        } return -1;
    }
    int main()
    {
        char c[10]; string s="";
        for(int i=1;i<=4;i++){
            scanf("%s",c+1);
            s=s+c[1]+c[2]+c[3]+c[4];
        }
        q.push(s);mp[s]=1;
        printf("%d
    ",bfs());
        return 0;
    }
  • 相关阅读:
    String类可以被继承吗?我们来聊聊final关键字!
    微信小程序中使用阿里ICON图标
    兼容iphone x刘海的正确姿势
    解决ios下部分手机在input设置为readonly属性时,依然显示光标
    react jsx 中使用 switch case 示例
    react 中使用 JsBarcode 显示条形码
    解决IDEA输入法输入中文候选框不显示问题
    svn提交代码失败提示清理(清理失败并且报错信息乱码解决办法)
    css笔记
    修改Mysql数据库的字符集
  • 原文地址:https://www.cnblogs.com/hua-dong/p/8119909.html
Copyright © 2020-2023  润新知