给出两个坐标,问你按象棋马走日的方式最少需要跳几次
因为涉及到最少所以我就想到了优先队列
这个题很水,但是读入很奇葩!
在杭电上我用cin string和scanf char[]就会超时
但是用cin char[]就不超时了...
刚刚想了下这道题好像没有必要使用优先队列,因为每次遍历的都是当前步数最少的状态
没有别的条件限制,所以直接用队列即可,把优先队列换成队列快了600ms...
代码如下:
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAXN 1010
#define LL long long
using namespace std;
bool vis[10][10][MAXN];
int dir[8][2] = {{-2,-1}, {-2,1}, {-1,-2}, {-1,2},
{1,-2}, {1,2}, {2,-1}, {2,1}};
struct Node {
int x, y, times;
bool operator < (const Node &rhs) const {
return times > rhs.times;
}
}start, end;
queue<Node> q;
void judgequeue(int x, int y, int times) {
if(x>=1 && x<=8 && y>=1 && y<=8 && !vis[x][y][times]) {
Node tmp;
tmp.x = x;
tmp.y = y;
tmp.times = times;
q.push(tmp);
}
}
int BFS() {
memset(vis, 0, sizeof(vis));
while(!q.empty())
q.pop();
start.times = 0;
q.push(start);
while(!q.empty()) {
Node tmp = q.front();
vis[tmp.x][tmp.y][tmp.times] = true;
q.pop();
if(tmp.x==end.x && tmp.y==end.y)
return tmp.times;
for(int i=0; i<8; ++i)
judgequeue(tmp.x+dir[i][0], tmp.y+dir[i][1], tmp.times+1);
}
return 0;
}
int main(void) {
int ans;
char str1[5], str2[5];
while(cin >> str1 >> str2) {
memset(vis, 0, sizeof(vis));
start.x = str1[0]-'a';
start.y = str1[1]-'0';
start.x++;
end.x = str2[0]-'a';
end.y = str2[1]-'0';
end.x++;
ans = BFS();
printf("To get from %s to %s takes %d knight moves.\n", str1, str2, ans);
}
return 0;
}