Advertisement
erek1e

Offcut - BIO 2022 Round 2

Mar 28th, 2023
496
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.69 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. /// Euler Path
  6.  
  7. const int MAX_E = 1<<19 + 1;
  8.  
  9. vector<vector<pair<int, int>>> g;
  10. int edge[MAX_E][2];
  11. bool usedE[MAX_E];
  12. inline int getOther(int id, int v) {
  13.     return v ^ edge[id][0] ^ edge[id][1];
  14. }
  15. vector<int> path; // of edges
  16.  
  17. int main() {
  18.     ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  19.     freopen("input.txt", "r", stdin);
  20.     freopen("output.txt", "w", stdout);
  21.  
  22.     int r, c; cin >> r >> c;
  23.     vector<vector<int>> grid(r, vector<int>(c));
  24.     for (vector<int> &row : grid) {
  25.         for (int &cell : row) cin >> cell;
  26.     }
  27.  
  28.     /// Turn into graph on collectibles with offcuts being edges
  29.     int n = r*c/4;
  30.     g.resize(1+n);
  31.     /// Cut it in any way - it will still be possible
  32.     int nextOffcut = 1;
  33.     for (int i = 0; i < r; ++i) {
  34.         for (int j = 0; j < c; j+=2) {
  35.             int ii = i, jj = j, pairKey = nextOffcut<<1;
  36.             if (j+1 < c) ++jj;
  37.             else if (i % 2 == 0) ++ii, ++pairKey;
  38.             else continue;
  39.             ++nextOffcut;
  40.  
  41.             int x = grid[i][j], y = grid[ii][jj];
  42.             // second value in pair indicates what to print - which is double the index of the offcut plus 1 if vertical
  43.             g[x].emplace_back(y, pairKey);
  44.             g[y].emplace_back(x, pairKey);
  45.             edge[pairKey/2][0] = x, edge[pairKey/2][1] = y;
  46.         }
  47.     }
  48.  
  49.     vector<int> group[2];
  50.     /// Distribute offcuts as alternating edges in euler path(s)
  51.     int cuts = nextOffcut-1;
  52.     for (int id = 1; id <= cuts; ++id) { // go through edges
  53.         if (usedE[id]) continue;
  54.         path.clear();
  55.         // find euler path in this connected component
  56.         // doing this with my own stack below since otherwise there is a segmentation fault on large test cases
  57.  
  58.         stack<pair<int, int>> st; // contains the node and edge
  59.         st.emplace(edge[id][0], 0);
  60.         while (!st.empty()) {
  61.             int node = st.top().first;
  62.             if (g[node].empty()) {
  63.                 if (st.top().second) path.push_back(st.top().second);
  64.                 st.pop();
  65.             } else {
  66.                 int id = g[node].back().second;
  67.                 g[node].pop_back();
  68.                 if (usedE[id/2]) continue;
  69.                 usedE[id/2] = true;
  70.                 st.emplace(getOther(id/2, node), id);
  71.             }
  72.         }
  73.  
  74.         for (int i = 0; i < path.size(); ++i) {
  75.             group[i&1].push_back(path[i]);
  76.         }
  77.     }
  78.  
  79.     /// Print the answer
  80.     for (int gr = 0; gr <= 1; ++gr) {
  81.         for (int key : group[gr]) {
  82.             cout << (key>>1) << ((key&1) ? 'V' : 'H') << ' ';
  83.         }
  84.         cout << endl;
  85.     }
  86.     return 0;
  87. }
  88.  
Tags: Bio
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement