(新版)SJTU-OJ-1031. 大脸上课

题目描述

由于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 2N+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 20Ai,Bi,X,Y20

50 % 50\% 50%的数据, − 100 ≤ A i , B i , X , Y ≤ 100 -100 \leq Ai, Bi, X, Y \leq 100 100Ai,Bi,X,Y100

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 N10,000,500Ai,Bi,X,Y500

题目解答

      学会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 N10,000,500Ai,Bi,X,Y500,所以我们不妨用数组地图的 ( 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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值