题目描述
由于dota水平太差被高手排斥,大脸同学最近迷上了打FIFA(虽然踢的依旧很臭)。一天晚上大脸通宵达旦和室友大战了三百回合,早上自然起晚了,可他又十分害怕迟到。
危难时刻,他拿出了自己的GPS,他发现以寝室为原点(坐标为 ( 0 , 0 ) (0,0) (0,0)),上课教室的坐标为 ( X , Y ) (X,Y) (X,Y),每个时间单位他可以向东西南北某个方向走一步。如 ( 0 , 0 ) (0,0) (0,0)可以到达 ( 0 , 1 ) , ( 1 , 0 ) , ( 0 , − 1 ) , ( − 1 , 0 ) (0,1),(1,0),(0,-1),(-1,0) (0,1),(1,0),(0,−1),(−1,0)。
他希望尽快走到教室,然而事情没有这么简单,因为一路上还有许多艰难险阻,比如大脸不会游泳,所以他不可能走到思春湖或者思源湖里(除非他觉得准时到达无望,一怒投湖)。具体来说,有 N N N个障碍,第i个障碍的坐标是 ( A i , B i ) (A_i, B_i) (Ai,Bi)。
于是大脸求助于你,请问大脸到达教室需要的最少时间是多少?
输入格式
第一行,三个整数 X , Y , N X,Y,N X,Y,N。
第 2 ⋯ N + 1 2 \cdots N+1 2⋯N+1行,第 i + 1 i+1 i+1行两个整数 ( A i , B i ) (A_i, B_i) (Ai,Bi)。
输出格式
一行一个整数,表示大脸需要的最少时间。
样例输入
1 2 7
0 2
-1 3
3 1
1 1
4 2
-1 1
2 2
教室的坐标是 ( 1 , 2 ) (1,2) (1,2). 障碍物是 ( 0 , 2 ) ; ( − 1 , 3 ) ; ( 3 , 1 ) ; ( 1 , 1 ) ; ( 4 , 2 ) ; ( − 1 , 1 ) ; ( 2 , 2 ) (0,2);(−1,3);(3,1);(1,1);(4,2);(−1,1);(2,2) (0,2);(−1,3);(3,1);(1,1);(4,2);(−1,1);(2,2):
4 . . . . . . . .
3 . M . . . . . .
2 . . M C M . M .
1 . M . M . M . .
0 . . * . . . . .
-1 . . . . . . . .
-2-1 0 1 2 3 4 5
样例输出
11
*代表大脸的最佳线路。
4 ******* . . . .
3 * M . * . . . .
2 * . M C M . M .
1 * M . M . M . .
0 ***** . . . . .
-1 . . . . . . . .
-2-1 0 1 2 3 4 5
数据范围
30 % 30\% 30%的数据, − 20 ≤ A i , B i , X , Y ≤ 20 -20 \leq Ai, Bi, X, Y \leq 20 −20≤Ai,Bi,X,Y≤20
50 % 50\% 50%的数据, − 100 ≤ A i , B i , X , Y ≤ 100 -100 \leq Ai, Bi, X, Y \leq 100 −100≤Ai,Bi,X,Y≤100
100 % 100\% 100%的数据, N ≤ 10 , 000 , − 500 ≤ A i , B i , X , Y ≤ 500 N\leq 10,000, -500 \leq Ai, Bi, X, Y \leq 500 N≤10,000,−500≤Ai,Bi,X,Y≤500
题目解答
学会BFS(BFS搜索传送门 (新版)SJTU-OJ-1028. 采购)之后就没有什么难度了,这题目唯一需要的坐标平移,考虑到题目数据,
100
%
100\%
100%的数据,
N
≤
10
,
000
,
−
500
≤
A
i
,
B
i
,
X
,
Y
≤
500
N\leq 10,000, -500 \leq Ai, Bi, X, Y \leq 500
N≤10,000,−500≤Ai,Bi,X,Y≤500,所以我们不妨用数组地图的
(
500
,
500
)
(500,500)
(500,500) 表示真实的原点
(
0
,
0
)
(0,0)
(0,0) 。
然后这个题目不能走的地方是单独列举出来的,就用一个 while
语句 读取即可,然后把地图上做个标记(我是标记为0),其余的代码抄前面的,没有什么特别好说的,不是很难。
#include <iostream>
#include <string.h>
#include <queue>
using namespace std;
class node
{
public:
int x;
int y;
};
node departure, destination;
int testmap[1010][1010];
int step[1010][1010];
int x, y, n;
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
bool bfs_CheckNextstep(node checkobject)
{
if (checkobject.x < 0 || checkobject.x >= 1010)
return false;
if (checkobject.y < 0 || checkobject.y >= 1010)
return false;
if (testmap[checkobject.x][checkobject.y] == 0)
return false;
if (step[checkobject.x][checkobject.y] > 0)
return false;
else
return true;
}
int bfs_Main(node departure)
{
memset(step, 0, sizeof(step));
// 首先定义一个队列!
queue<node> bfsque;
bfsque.push(departure);
node currentplace, nextplace;
while (!bfsque.empty())
{
currentplace = bfsque.front();
bfsque.pop(); // 把最前面的元素弹出去!
for (int i = 0; i < 4; i++)
{
nextplace.x = currentplace.x + dx[i];
nextplace.y = currentplace.y + dy[i];
if (bfs_CheckNextstep(nextplace) == true)
{
step[nextplace.x][nextplace.y] = step[currentplace.x][currentplace.y] + 1;
bfsque.push(nextplace);
}
if (nextplace.x == destination.x && nextplace.y == destination.y)
{
while (!bfsque.empty())
{
bfsque.pop();
}
return step[destination.x][destination.y];
}
}
}
// return step[destination.x][destination.y];
}
int main()
{
memset(testmap, 1, sizeof(testmap)); // 初始化都可以走
cin >> x >> y >> n;
destination.x = 500 + x;
destination.y = 500 + y;
int temp1, temp2;
while(n--)
{
cin >> temp1 >> temp2;
testmap[500 + temp1][500 + temp2] = 0;
}
departure.x = 500;
departure.y = 500;
cout << bfs_Main(departure);
system("pause");
return 0;
}