codevs上的分类是广搜,但我竟然一直在用深搜做,于是就gg了一个多小时,,
在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局。
● | ○ | ● | |
○ | ● | ○ | ● |
● | ○ | ● | ○ |
○ | ● | ○ | |
从文件中读入一个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;
}