Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <algorithm>
- #include <cmath>
- #include <vector>
- #include <set>
- #include <map>
- #include <stack>
- #include <queue>
- #include <deque>
- #include <unordered_map>
- #include <numeric>
- #include <iomanip>
- using namespace std;
- #define pii pair<int, int>
- #define FAST ios_base::sync_with_stdio(false); cin.tie(NULL)
- const int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};
- const int MOD = 1e9;
- const int MAX = 100005;
- int n;
- pii laser, barn;
- vector<pii> mirror;
- vector<int> x_comp, y_comp;
- vector<int> coords[MAX][2]; // 0 = x, 1 = y
- int visitedx[MAX][2], visitedy[MAX][2];
- struct vertex{
- int x, y, dir, dist;
- void print(){
- cout << "Pushed to queue: " << x << " " << y << " " << dir << " " << dist << "\n";
- }
- };
- int main() {
- FAST;
- freopen("lasers.in", "r", stdin);
- freopen("lasers.out", "w", stdout);
- cin >> n >> laser.first >> laser.second >> barn.first >> barn.second;
- mirror.resize(n + 2);
- for(int i = 0; i < n + 2; i++){
- if(i == n){
- mirror[i] = laser;
- }
- else if(i == n + 1){
- mirror[i] = barn;
- }
- else{
- cin >> mirror[i].first >> mirror[i].second;
- }
- x_comp.push_back(mirror[i].first); y_comp.push_back(mirror[i].second);
- }
- // Coordinate Compression
- sort( x_comp.begin(), x_comp.end() );
- x_comp.erase( unique( x_comp.begin(), x_comp.end() ), x_comp.end() );
- sort( y_comp.begin(), y_comp.end() );
- y_comp.erase( unique( y_comp.begin(), y_comp.end() ), y_comp.end() );
- for(int i = 0; i < n + 2; i++){
- mirror[i].first = (int)(lower_bound(x_comp.begin(), x_comp.end(), mirror[i].first) - x_comp.begin());
- mirror[i].second = (int)(lower_bound(y_comp.begin(), y_comp.end(), mirror[i].second) - y_comp.begin());
- // cout << mirror[i].first << " " << mirror[i].second << "\n";
- coords[mirror[i].second][0].push_back(mirror[i].first);
- coords[mirror[i].first][1].push_back(mirror[i].second);
- }
- laser = mirror[n];
- barn = mirror[n + 1];
- queue<vertex> q;
- vertex init;
- init.x = laser.first;
- init.y = laser.second;
- init.dir = 0;
- init.dist = 0;
- vertex init2 = init;
- init2.dir = 1;
- q.push(init);
- q.push(init2);
- int ans = 2e9;
- while(!q.empty()){
- vertex cur = q.front();
- q.pop();
- int curx = cur.x, cury = cur.y, cur_dir = cur.dir, cur_dist = cur.dist;
- // cout << "BFS: " << curx << " " << cury << " " << cur_dir << " " << cur_dist << "\n";
- if(!(curx == laser.first and cury == laser.second)){
- visitedx[curx][cur_dir] = 1;
- visitedy[cury][cur_dir] = 1;
- }
- if(curx == barn.first or cury == barn.second){
- ans = min(ans, cur_dist);
- }
- if(cur_dir == 0){
- for(auto nxtx: coords[cury][cur_dir]){
- vertex nxt;
- nxt.x = nxtx;
- nxt.y = cury;
- nxt.dir = 1 - cur_dir;
- nxt.dist = cur_dist + 1;
- if(visitedx[nxt.x][nxt.dir] == 0 and visitedy[nxt.y][nxt.dir] == 0 and !(nxt.x == laser.first and nxt.y == laser.second)){
- q.push(nxt);
- // nxt.print();
- }
- }
- }
- else{
- for(auto nxty: coords[curx][cur_dir]){
- vertex nxt;
- nxt.x = curx;
- nxt.y = nxty;
- nxt.dir = 1 - cur_dir;
- nxt.dist = cur_dist + 1;
- if(visitedx[nxt.x][nxt.dir] == 0 and visitedy[nxt.y][nxt.dir] == 0 and !(nxt.x == laser.first and nxt.y == laser.second)){
- q.push(nxt);
- // nxt.print();
- }
- }
- }
- }
- if(ans == 2e9){
- cout << "-1\n";
- }
- else{
- cout << ans;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement