xuanquang1999

I. Infinite Chess

Nov 27th, 2022
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.00 KB | None | 0 0
  1. // Fuck my life
  2.    
  3. #include <bits/stdc++.h>
  4.  
  5. using namespace std;
  6.  
  7. typedef pair<int, int> pii;
  8.  
  9. const int MAXN = 2005;
  10. const int oo = (int)1e9 + 7;
  11.  
  12. // Board is rotated for easier imagination
  13.  
  14. struct Piece {
  15.     char type;
  16.     int r, c;
  17. };
  18.  
  19. struct Strip {
  20.     int r1, r2, c;
  21. };
  22.  
  23. struct Rect {
  24.     int height;
  25.     bool forbid, isStart, isFinish;
  26. };
  27.  
  28. bool inBoard(int c) {return c >= 1 && c <= 8;}
  29.  
  30. vector<Strip> getStrips(vector<Piece> pieces) {
  31.     vector<set<int>> blocks(9);
  32.     for(int c = 1; c <= 8; ++c) {
  33.         blocks[c].insert(-20);
  34.         blocks[c].insert(1e8 + 20);
  35.     }
  36.     for(Piece p: pieces) {
  37.         blocks[p.c].insert(p.r);
  38.     }
  39.  
  40.     auto cellBlocked = [&](int r, int c) {
  41.         return blocks[c].count(r);
  42.     };
  43.  
  44.     vector<Strip> res;
  45.     auto addCell = [&](int r, int c) {
  46.         // printf("addCell %d %d\n", r, c);
  47.         res.push_back({r, r, c});
  48.     };
  49.  
  50.     auto addStripKnight = [&](int r, int c) {
  51.         int DX[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
  52.         int DY[8] = {1, 2, 2, 1, -1, -2, -2, -1};
  53.         for(int dir = 0; dir < 8; ++dir) {
  54.             int curR = r + DX[dir], curC = c + DY[dir];
  55.             if (inBoard(curC) && !cellBlocked(curR, curC))
  56.                 addCell(curR, curC);
  57.         }
  58.     };
  59.  
  60.     auto addStripKing = [&](int r, int c) {
  61.         for(int curR = r-1; curR <= r+1; ++curR) {
  62.             for(int curC = c-1; curC <= c+1; ++curC) {
  63.                 // printf("curR, curC: %d %d\n", curR, curC);
  64.                 if (!(curR == r && curC == c) && inBoard(curC) && !cellBlocked(curR, curC)) addCell(curR, curC);
  65.             }
  66.         }
  67.     };
  68.  
  69.     auto addStripBishop = [&](int r, int c) {
  70.         int DX[4] = {-1, 1, 1, -1};
  71.         int DY[4] = {-1, -1, 1, 1};
  72.         for(int dir = 0; dir < 4; ++dir) {
  73.             int curR = r, curC = c;
  74.             while (true) {
  75.                 curR += DX[dir]; curC += DY[dir];
  76.                 if (!inBoard(curC) || cellBlocked(curR, curC)) break;
  77.                 addCell(curR, curC);
  78.             }
  79.         }
  80.     };
  81.  
  82.     auto addStripRook = [&](int r, int c) {
  83.         for(int deltaC = -1; deltaC <= 1; deltaC += 2) {
  84.             int curR = r, curC = c;
  85.             while (true) {
  86.                 curC += deltaC;
  87.                 if (!inBoard(curC) || cellBlocked(curR, curC)) break;
  88.                 addCell(curR, curC);
  89.             }
  90.         }
  91.  
  92.         int rDown = *blocks[c].upper_bound(r);
  93.         int rUp = *prev(blocks[c].lower_bound(r));
  94.         res.push_back({rUp, rDown, c});  
  95.     };
  96.    
  97.     auto addStripQueen = [&](int r, int c) {
  98.         addStripBishop(r, c);
  99.         addStripRook(r, c);
  100.     };
  101.  
  102.     for(Piece p: pieces) {
  103.         addCell(p.r, p.c);
  104.         if (p.type == 'K') addStripKing(p.r, p.c);
  105.         else if (p.type == 'Q') addStripQueen(p.r, p.c);
  106.         else if (p.type == 'R') addStripRook(p.r, p.c);
  107.         else if (p.type == 'B') addStripBishop(p.r, p.c);
  108.         else if (p.type == 'N') addStripKnight(p.r, p.c);
  109.     }
  110.    
  111.     return res;
  112. }
  113.  
  114. vector<vector<Rect>> getBoard(vector<Strip> strips, int xs, int ys, int xt, int yt) {
  115.     set<int> _poi;
  116.     _poi.insert(-20);
  117.     _poi.insert(1e8+20);
  118.  
  119.     auto addToPoi = [&](int x) {
  120.         if (x >= -20 && x <= 1e8+20)
  121.             _poi.insert(x);
  122.     };
  123.     for(int delta = -2; delta <= 2; ++delta) {
  124.         for(Strip s: strips) {
  125.             addToPoi(s.r1 + delta);
  126.             addToPoi(s.r2 + delta);    
  127.         }
  128.         addToPoi(xs + delta);
  129.         addToPoi(xt + delta);    
  130.     }
  131.  
  132.     vector<int> poi(_poi.begin(), _poi.end());
  133.  
  134.     // for(int x: poi) printf("%d ", x);
  135.     // puts("");
  136.    
  137.     vector<vector<int>> addStrip(9, vector<int>());
  138.     vector<vector<int>> removeStrip(9, vector<int>());
  139.     for(Strip s: strips) {
  140.         addStrip[s.c].push_back(s.r1);
  141.         removeStrip[s.c].push_back(s.r2+1);
  142.     }
  143.     for(int c = 1; c <= 8; ++c) {
  144.         sort(addStrip[c].begin(), addStrip[c].end());
  145.         sort(removeStrip[c].begin(), removeStrip[c].end());
  146.     }
  147.  
  148.     vector<vector<Rect>> res(poi.size()-1, vector<Rect>(9));
  149.  
  150.     for(int c = 1; c <= 8; ++c) {
  151.         int iAdd = 0, iRemove = 0, cnt = 0;
  152.         for(int i = 0; i < poi.size()-1; ++i) {
  153.             while (iAdd < addStrip[c].size() && addStrip[c][iAdd] <= poi[i]) {
  154.                 ++cnt;
  155.                 ++iAdd;
  156.             }
  157.             while (iRemove < removeStrip[c].size() && removeStrip[c][iRemove] <= poi[i]) {
  158.                 --cnt;
  159.                 ++iRemove;
  160.             }            
  161.             res[i][c] = {poi[i+1]-poi[i], cnt > 0, poi[i] == xs && c == ys, poi[i] == xt && c == yt};            
  162.         }
  163.     }
  164.  
  165.     return res;
  166. }
  167.  
  168. int getDistFromStartToFinish(vector<vector<Rect>> board) {
  169.     pii start, finish;
  170.     int n = board.size();
  171.     for(int i = 0; i < n; ++i) {
  172.         for(int j = 1; j <= 8; ++j) {
  173.             if (board[i][j].isStart) start = {i, j};
  174.             if (board[i][j].isFinish) finish = {i, j};
  175.         }
  176.     }
  177.  
  178.     vector<vector<int>> dist(n, vector<int>(9, oo));    
  179.     vector<vector<bool>> avail(n, vector<bool>(9, true));
  180.     priority_queue<pair<int, pii>> q;
  181.  
  182.     dist[start.first][start.second] = 0;
  183.     q.push({0, start});
  184.  
  185.     while (!q.empty()) {
  186.         pii cur = q.top().second; q.pop();
  187.         int x = cur.first, y = cur.second;
  188.         if (board[x][y].isFinish) return dist[x][y];
  189.         if (!avail[x][y]) continue;
  190.  
  191.         avail[x][y] = false;
  192.         for(int dx = -1; dx <= 1; ++dx) {
  193.             for(int dy = -1; dy <= 1; ++dy) {
  194.                 int u = x + dx, v = y + dy;
  195.                 int w = (dx != 0) ? board[x][y].height : 1;
  196.                 if (u >= 0 && u < n && v >= 1 && v <= 8 && avail[u][v] && !board[u][v].forbid && dist[u][v] > dist[x][y] + w) {
  197.                     dist[u][v] = dist[x][y] + w;
  198.                     q.push({-dist[u][v], {u, v}});
  199.                 }
  200.             }
  201.         }
  202.     }
  203.  
  204.     return -1;
  205. }
  206.  
  207. int main() {
  208.     freopen("input.txt", "r", stdin);
  209.    
  210.     int xs, ys;
  211.     scanf("%d%d", &xs, &ys);
  212.     int xt, yt;
  213.     scanf("%d%d", &xt, &yt);
  214.  
  215.     int n;
  216.     cin >> n;
  217.     vector<Piece> pieces;
  218.     for(int i = 0; i < n; ++i) {
  219.         string type; int x, y;
  220.         cin >> type >> x >> y;
  221.         pieces.push_back({type[0], x, y});
  222.     }
  223.  
  224.     vector<Strip> strips = getStrips(pieces);
  225.     // for(Strip s: strips) {
  226.     //     printf("r1, r2, c: %d %d %d\n", s.r1, s.r2, s.c);
  227.     // }
  228.  
  229.     vector<vector<Rect>> board = getBoard(strips, xs, ys, xt, yt);
  230.     // for(int i = 0; i < board.size(); ++i) {
  231.     //     for(int j = 1; j <= 8; ++j) {
  232.     //         printf("%d ", board[i][j].forbid ? 0 : 1);            
  233.     //     }
  234.     //     puts("");
  235.     // }
  236.     // for(int i = 0; i < board.size(); ++i) {
  237.     //     for(int j = 1; j <= 8; ++j) {
  238.     //         printf("(%d, %d) ", board[i][j].height, board[i][j].forbid ? 0 : 1);            
  239.     //     }
  240.     //     puts("");
  241.     // }
  242.  
  243.     int ans = getDistFromStartToFinish(board);
  244.  
  245.     printf("%d\n", ans);
  246.  
  247.     return 0;
  248. }
Add Comment
Please, Sign In to add comment