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;
}
原文地址:https://www.cnblogs.com/hua-dong/p/8119909.html