poj2243 knight moves
广搜:最先搜到的即为最优的。该题为马跑,开始弄错了。
开始设一个struct dx[],dy[]表示走一步后的坐标变化。用队列,每个队列元素遍历周围8个,子节点再遍历,如此循环,直到有横纵坐标满足为止。
#include<iostream>
#include<string>
#include<queue>
using namespace std;
void init();
struct node
{
int x,y;
int depth,flag;//depth表示深度,即需走的步数;flag=0:未访问,1:访问过;2:周围8个全访问过。
};
node nod[9][9];
int dx[]={-1,1,-1,1,2,-2,2,-2};
int dy[]={-2,2,2,-2,1,-1,-1,1};
int bfs(node b,node e)
{
queue<node> queue1;
b.flag=1;
queue1.push(b);
node s;
if(b.x==e.x&&b.y==e.y) return 0;
while(!queue1.empty())
{
s=queue1.front();
queue1.pop();//每次要把队首pop掉。
int tepx;
int tepy;
for(int i=0;i<8;i++)
{
tepx=s.x+dx[i];
tepy=s.y+dy[i];
if(tepx<1||tepx>8||tepy<1||tepy>8)//超出格子范围
continue;
if(nod[tepx][tepy].flag==0)
{
nod[tepx][tepy].depth=s.depth+1;//每次在原步数上+1;
if(tepx==e.x&&tepy==e.y) return nod[tepx][tepy].depth;//先+1后,再return开始弄错了!!
nod[tepx][tepy].flag=1;
queue1.push(nod[tepx][tepy]);
}
}
s.flag=2;
}
}
void init()
{
for(int i=1;i<=8;i++)
for(int j=1;j<=8;j++)
{
nod[i][j].x=i;
nod[i][j].y=j;
nod[i][j].flag=0;
nod[i][j].depth=0;
}
}
int main()
{
string bm,em;
node b,e;
while(cin>>bm>>em)
{
init();//每输入一对,要初始化
b.flag=0;//b,e是在外面定义的,要赋初始值。flag、depth一定要赋初值0,弄错好久!!!!!!!
b.depth=0;
b.x=bm[0]-'a'+1;
b.y=bm[1]-'0';
e.x=em[0]-'a'+1;
e.y=em[1]-'0';
cout<<"To get from " <<bm<<" to "<<em<<" takes "<<bfs(b,e)<<" knight moves."<<endl;
}
}