四字连棋(深搜)

codevs上的分类是广搜,但我竟然一直在用深搜做,于是就gg了一个多小时,,

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

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

输出描述 Output Description

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

样例输入 Sample Input

BWBO
WBWB
BWBW
WBWO

样例输出 Sample Output

5


开始我以为这是一道简单的深搜题,于是就打了个例如走迷宫题目的框架,没想到打着打着就打不下去了,,就开始艰苦的冥想,,不过代码还是很易懂的,排错时间也不是很长

#include<iostream>
#include<cstdio>
using namespace std;
int map[5][5],next[4][2]={{0,-1},{0,1},{1,0},{-1,0}};
int x1,x2,y1,y2,dep,t;
int pd(int x,int y,int z)
{
    if(map[x][y]!=z&&x<=4&&x>=1&&y<=4&&y>=1)//判断越界
        return 1;
    return 0;
}
int wsk()//使用dalao wangshuaikun的名字定义的函数,用来判断同行同列
{
    int i;
    for(i=1;i<=4;i++)
    {
        if(map[1][i]==map[2][i]&&map[2][i]==map[3][i]&&map[3][i]==map[4][i])
            return 1;
        if(map[i][1]==map[i][2]&&map[i][2]==map[i][3]&&map[i][3]==map[i][4])
            return 1;
    }
    if(map[1][1]==map[2][2]&&map[2][2]==map[3][3]&&map[3][3]==map[4][4])
        return 1;
    if(map[1][4]==map[2][3]&&map[2][3]==map[3][2]&&map[3][2]==map[4][1])
        return 1;
    return 0;
}
void dfs(int x,int y,int p,int q,int pre,int step)//深搜函数部分(很简单,感觉不用说那么多,,)
{
    if(wsk())
    {
        t=1;
        return ;
    }
    else
        if(step>dep)
            return ;
    int i;
    for(i=0;i<4;i++)
    {
        int nx=x+next[i][0];
        int ny=y+next[i][1];
        int np=p+next[i][0];
        int nq=q+next[i][1];
        if(pd(nx,ny,pre))
        {
            swap(map[x][y],map[nx][ny]);
            dfs(nx,ny,p,q,map[x][y],step+1);
            swap(map[x][y],map[nx][ny]);
        }
        if(pd(np,nq,pre))
        {
            swap(map[p][q],map[np][nq]);
            dfs(x,y,np,nq,map[p][q],step+1);
            swap(map[p][q],map[np][nq]);
        }
    }
}
int main()
{
    int i,j;
    for(i=1;i<=4;i++)
        for(j=1;j<=4;j++)
        {
            char ch;
            cin>>ch;
            if(ch=='B')
                map[i][j]=1;
            else
                if(ch=='W')
                    map[i][j]=2;
                else
                    map[i][j]=3;//用1,2,3标记黑子白子空格
            if(map[i][j]==3&&x1==0)
            {
                x1=i;
                y1=j;
            }
            else
                if(map[i][j]==3)
                {
                    x2=i;
                    y2=j;
                }
        }
    while(1)
    {
       dfs(x1,y1,x2,y2,1,1);
       dfs(x1,y1,x2,y2,2,1);
       if(t)
       {
           printf("%d\n",dep);
           return 0;
       }
       dep++;
    }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值