跳马(象棋)

来源:互联网 发布:avast 小红伞 知乎 编辑:程序博客网 时间:2024/05/16 23:35

描述
在国际象棋中,马的走法与中车象棋类似,即俗话说的“马走日”,下图所示即国际象棋中马(K)在一步能到达的格子(其中黑色的格子是能到达的位置)。

现有一200*200大小的国际象棋棋盘,棋盘中仅有一个马,给定马的当前位置(S)和目标位置(T),求出马最少需要多少跳才能从当前位置到达目标位置。
 
输入
本题包含多个测例。输入数据的第一行有一个整数N(1<=N<=1000),表示测例的个数,接下来的每一行有四个以空格分隔的整数,分别表示马当前位置及目标位置的横、纵坐标C(x,y)和G(x,y)。坐标由1开始。
 
输出
对于每个测例,在单独的一行内输出一个整数,即马从当前位置跳到目标位置最少的跳数。
 
输入样例
2
1 1 2 1
1 5 5 1
 
输出样例
3
4



#include<stdio.h>
#include<queue>
using namespace std;


int init(); //初始化数据。 
int bfs();  //计算 
int save(); //保存每个数据计算出来的步数 

queue<int>q1;
queue<int>q2;
//定义一个204行204列的棋盘,边框的两行两列是为了防止数组越界,但马不可以往那走。step记录步数。 
int a[204][204]={1},step[204][204]; 
int b[30],num=0;     //保存数据的数组。 
int x1,y1,x2,y2,n;  
int x,y;




int main()
{
int i,j;

scanf("%d",&n);
while(n>0) //输入数据个数为n个。 
{
//每一次算完都要把数据清除,防止干扰下一次计算。 
while(!q1.empty())
{
q1.pop();
}
while(!q2.empty())
{
q2.pop();
}
for(i=2; i<202; i++)
{
for(j=2; j<202; j++)
{
a[i][j]=0;
}
}
//下面是让边框的值都等于1,表示不可走,而此时数组也不会越界。 
for(i=0; i<2; i++)
{
for(j=0; j<204; j++)
{
a[i][j]=1;
a[j][i]=1;
}
}
for(i=202; i<204; i++)
{
for(j=0; j<204; j++)
{
a[i][j]=1;
a[j][i]=1;
}
}
scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
a[x1+1][y1+1]=1;//棋盘中坐标为1,即不可做,0表示可以走。 

init();

bfs();
n--;

}
for(i=0; i<num; i++)
{
printf("%d\n",b[i]);
}
return 0;





int init()
{
q1.push(x1+1);
q2.push(y1+1);
step[x1+1][y1+1]=0;//初始化,因为我的坐标有两列两行边框,所以坐标需要整体加1。表示这个坐标为第0步。 

}




int bfs()
{
while(!q1.empty())
{
x=q1.front();
q1.pop();
y=q2.front();
q2.pop();

//如果等于目标坐标,就把数据保存下来,并结束。 
if(x==x2+1&&y==y2+1)//上面说过坐标需要整体加1。 
{
save();
return 0;
}

if(a[x-2][y-1]==0)
{
q1.push(x-2);
q2.push(y-1);
a[x-2][y-1]=1;//用过之后就让坐标等于1,保证下次不再用。 
step[x-2][y-1]=step[x][y]+1;
}
if(a[x-2][y+1]==0)
{
q1.push(x-2);
q2.push(y+1);
a[x-2][y+1]=1;
step[x-2][y+1]=step[x][y]+1;
}
if(a[x-1][y-2]==0)
{
q1.push(x-1);
q2.push(y-2);
a[x-1][y-2]=1;
step[x-1][y-2]=step[x][y]+1;

if(a[x-1][y+2]==0)
{
q1.push(x-1);
q2.push(y+2);
a[x-1][y+2]=1;
step[x-1][y+2]=step[x][y]+1;
}
if(a[x+1][y-2]==0)
{
q1.push(x+1);
q2.push(y-2);
a[x+1][y-2]=1;
step[x+1][y-2]=step[x][y]+1;
}
if(a[x+1][y+2]==0)
{
q1.push(x+1);
q2.push(y+2);
a[x+1][y+2]=1;
step[x+1][y+2]=step[x][y]+1;
}
if(a[x+2][y-1]==0)
{
q1.push(x+2);
q2.push(y-1);
a[x+2][y-1]=1;
step[x+2][y-1]=step[x][y]+1;
}
if(a[x+2][y+1]==0)
{
q1.push(x+2);
q2.push(y+1);
a[x+2][y+1]=1;
step[x+2][y+1]=step[x][y]+1;

}
return 0;
}


int save()
{
b[num]=step[x][y];//保存每一个数据所用步数。 
num++;
}

原创粉丝点击