四子连棋

【题目描述】

在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局。

 
 

 

【输入描述】

从文件中读入一个4*4的初始棋局,黑棋子用B表示,白棋子用W表示,空格地带用O表示。

【输出描述】

用最少的步数移动到目标棋局的步数。

【样例输入】

BWBO
WBWB
BWBW
WBWO

【样例输出】

5

DFS:

源代码:

#include<iostream>
using namespace std;
#define INF 100000000
int ans=10,i[5][5],x[4]={-1,0,0,1},y[4]={0,-1,1,0}; //偷懒的好办法。
void Search(int t1,int t2,int num,int s)
{
    if (num>=ans) //回去吧。
      return;
    int t=INF;
    for (int a=1;a<=4;a++) //查询此情况是否合法。
    {
        if (i[a][1]==i[a][2]&&i[a][2]==i[a][3]&&i[a][3]==i[a][4])
          t=num;
        if (i[1][a]==i[2][a]&&i[2][a]==i[3][a]&&i[3][a]==i[4][a])
          t=num;
    }
    if (i[1][1]==i[2][2]&&i[2][2]==i[3][3]&&i[3][3]==i[4][4])
      t=num;
    if (i[1][4]==i[2][3]&&i[2][3]==i[3][2]&&i[3][2]==i[4][1])
      t=num;
    if (t<ans) //回去吧。
    {
        ans=t;
        return;
    }
    for (int a=0;a<4;a++)
      if (t1+x[a]<5&&t1+x[a]>0&&t2+y[a]<5&&t2+y[a]>0&&i[t1+x[a]][t2+y[a]]==s) //符合条件。
      {
          i[t1][t2]=s;
          i[t1+x[a]][t2+y[a]]=0;
          s=s==1?2:1;
          for (int b=1;b<=4;b++)
            for (int c=1;c<=4;c++)
              if (!i[b][c])
                Search(b,c,num+1,s);
          s=s==1?2:1; //回溯。
          i[t1+x[a]][t2+y[a]]=s;
          i[t1][t2]=0;
      }
}
int main() //DFS。
{
    for (int a=1;a<=4;a++)
      for (int b=1;b<=4;b++)
      {
          char t;
          cin>>t; //论字符串读入的坑爹性。
          if (t=='W')
            i[a][b]=1;
          if (t=='B')
            i[a][b]=2;
          if (t=='O')
            i[a][b]=0;
      }
    for (int a=1;a<=4;a++)
      for (int b=1;b<=4;b++)
        if (!i[a][b]) //黑白交替进行。
        {
            Search(a,b,0,1);
            Search(a,b,0,2);
        }
    cout<<ans;
    return 0;
}

BFS:

原文地址:https://www.cnblogs.com/Ackermann/p/5573165.html