題目:
Knight Moves
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3684 Accepted Submission(s): 2293
Of course you know that it is vice versa. So you offer him to write a program that solves the "difficult" part.
Your job is to write a program that takes two squares a and b as input and then determines the number of knight moves on a shortest route from a to b.
題目鏈接:
http://acm.hdu.edu.cn/showproblem.php?pid=1372
題意:
一個8*8的正方形棋盤,行用a-h標記,列用1-8標記。
給定兩個座標,要求你從一個座標到另一個座標的最小步數。
移動和象棋中的馬一樣,走 “日” 字。
思路:
廣搜8個方向
#include<iostream>
#include<queue>
using namespace std;
const int maxn = 10 +1;
int dir[8][2] = {-1,-2,1,-2,-1,2,1,2,-2,-1,-2,1,2,-1,2,1};
int used[maxn][maxn];
char a,b;
int x,y;
struct node
{
int x;
int y;
int t;
};
void bfs()
{
queue<node> q;
node start;
start.x = a - 'a' + 1;
start.y = x;
start.t = 0;
q.push(start);
used[start.x][start.y] = 1;
/* if(a = b && x == y)
{
cout<<"0 knight moves."<<endl;
}
@@@@*/
while(!q.empty())
{
node head = q.front();
q.pop();
if(head.x == b-'a'+1 && head.y == y) //結束條件 因爲之前在for循環裏面 所以用 if(New.x == b-'a'+1 && New.y == y) 造成錯誤
{
cout<<head.t<<" knight moves."<<endl;
return;
}
for(int i=0; i<8; i++)
{
node New;
New=head;
New.x = head.x + dir[i][0];
New.y = head.y + dir[i][1];
New.t = head.t + 1; //計算走過的路徑 把計數器定在結構體裏面 不會造成計數重複 錯誤
if(New.x>0 && New.x<=8 && New.y>0 && New.y<=8)//範圍這裏之前因爲start.x = a - 'a' + 1;沒有+1,導致範圍錯誤(豎的從0開始,橫的從1開始)
{
if(!used[New.x][New.y])
{
/* if(New.x == b-'a'+1 && New.y == y)
{
cout<<New.t<<" knight moves."<<endl;
return;
}*///如果是用這種做結束條件 要上面的那條語句@@@@,因爲起點和終點一樣的時候,在這裏已經是被擴展過的所以計數爲2
used[New.x][New.y] = 1;
q.push(New);
}
}
}
}
}
int main()
{
while(cin>>a>>x>>b>>y)
{
memset(used, 0, sizeof(used));
cout<<"To get from "<<a<<x<<" to "<<b<<y<<" takes ";
bfs();
}
return 0;
}
//