您的位置:首页 > 其它

POJ 1915 Knight Moves

2016-05-12 10:05 363 查看
题目链接:http://poj.org/problem?id=1915

题意:给定n*n的棋盘以及起点和终点,求马的最小步数。

思路:简单的bfs,可以用来练习双向bfs。

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <utility>
using namespace std;

#define rep(i,j,k) for (int i=j;i<=k;i++)
#define Rrep(i,j,k) for (int i=j;i>=k;i--)

#define Clean(x,y) memset(x,y,sizeof(x))
#define LL long long
#define ULL unsigned long long
#define inf 0x7fffffff
#define mod %100000007
const int dx[8] = {1,1,-1,-1,2,2,-2,-2};
const int dy[8] = {2,-2,2,-2,1,-1,1,-1};

const int maxn = 309;

int s[maxn][maxn];
int vis[maxn][maxn];
int n;
int stx,sty,edx,edy;

int x[maxn*maxn];
int y[maxn*maxn];

void init()
{
scanf("%d",&n);
scanf("%d %d %d %d",&stx,&sty,&edx,&edy);
Clean(vis,0);
Clean(s,0);
}

bool check(int xx,int yy)
{
return ( xx >= 0 && xx < n && yy >= 0 && yy < n );
}

int bfs()
{
int head,tail;
if ( stx == edx && sty == edy ) return 0;
head = tail = -1;
vis[stx][sty] = 1;  //起点出发标记1
vis[edx][edy] = 2;  //终点出发标记2
tail++;
x[tail] = stx,y[tail] = sty;//起点入队
tail++;
x[tail] = edx,y[tail] = edy;//终点入队
while(head<tail)
{
head++;
int xx,yy;
rep(i,0,7)
{
xx = x[head] + dx[i];
yy = y[head] + dy[i];
if ( !check(xx,yy) ) continue;
if ( vis[xx][yy] && vis[xx][yy] != vis[x[head]][y[head]] ) //此点被访问过而且分别是由起点和终点拓展得到
{
return s[xx][yy] + s[x[head]][y[head]] + 1; //两个点之间还有1步需要走
}
else if ( !vis[xx][yy] ) //新节点入队
{
tail++;
x[tail] = xx;
y[tail] = yy;
s[xx][yy] = s[x[head]][y[head]] + 1;
vis[xx][yy] = vis[x[head]][y[head]];
}
}
}
return -1;
}

int main()
{
int T;
cin>>T;

while(T--)
{
init();
printf("%d\n",bfs());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: