原题链接:Problem - 242C - Codeforces
题目大意:给你一个1e9 * 1e9的棋盘,给你n个区间 r a b,表示r行的第a到b列是可行区域。问你从x0y0到x1y1最少多少步走到(可以走这个格子的周围一圈八个位置)。
思路:注意题目最后说的一句话:
It is guaranteed that the total length of all given segments doesn't exceed 1e5.
最多给我们1e5个格子可以走,每个格子最多走到一遍,bfs没问题。所以把所有可以到的格子遍历找到然后放到set里(存坐标),再从起点bfs到终点。只要走到过的地方,如果下次再走到那么步数一定不会是最少的了,所以每走到一个点,就把这个点从set中删掉就可以了。
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
typedef pair<int, int> PII;
const double pi = acos(-1.0);
#define rep(i, n) for (int i = 1; i <= (n); ++i)
#define rrep(i, n) for (int i = n; i >= (1); --i)
typedef long long ll;
#define sqar(x) ((x)*(x))int dx[] = {-1, -1, -1, 0, 1, 1, 1, 0};
int dy[] = {-1, 0, 1, 1, 1, 0, -1, -1};struct node
{int x, y, step;
};int main()
{int x1, y1, x0, y0, n, r, a, b;scanf("%d %d %d %d", &x0, &y0, &x1, &y1);scanf("%d", &n);set<PII> s;rep(i, n){scanf("%d %d %d", &r, &a, &b);for(int j = a; j <= b; j++) s.insert({r, j});}queue<node> q;q.push(node{x0, y0, 0});s.erase({x0, y0});while(q.size()){auto temp = q.front();q.pop();if(temp.x == x1 && temp.y == y1){printf("%d", temp.step);return 0;}for(int i = 0; i < 8; i++){int xx = temp.x + dx[i];int yy = temp.y + dy[i];if(s.count({xx, yy})){q.push(node{xx, yy, temp.step + 1});s.erase({xx, yy});}}}printf("-1");return 0;
}