mr_dot_convict

1185-E-Polycrap_and_snakes.Codeforces-mr.convict

Jun 20th, 2019
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.43 KB | None | 0 0
  1. /*author* Priyanshu Shrivastav (from IIT Palakkad) *
  2.  * *_ __ ___  _ ______ ___  _ ____   ___  ___| |_  *
  3.  * | '_ ` _ \| '__/ __/ _ \| '_ \ \ / / |/ __| __| *
  4.  * | | | | | | | | (_| (_) | | | \ V /| | (__| |_  *
  5.  * |_| |_| |_|_|(_)___\___/|_| |_|\_/ |_|\___|\__| *
  6. When I wrote this, only God and I understood what I was doing
  7.  ** * * * * * * * Now, only God knows * * * * * * */
  8. #include         <bits/stdc++.h>
  9. using namespace std;
  10. #pragma GCC      optimize ("Ofast")
  11. #pragma GCC      optimize ("unroll-loops")
  12. #pragma GCC      target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  13.  
  14. #define IOS      ios_base::sync_with_stdio(false); cin.tie (nullptr)
  15. #define PREC     cout.precision (10); cout << fixed
  16. #define bg(x)    " [ " << #x << " : " << (x) << " ]"
  17. #define x        first
  18. #define y        second
  19. using ll = long long;
  20.  
  21. #define debug(args...) { \
  22.    string _s = #args; replace(_s.begin(), _s.end(), ',', ' ');\
  23.    stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); \
  24. }
  25. void err(istream_iterator<string> it) { it->empty();
  26.    cerr << " (Line : " << __LINE__ << ")" << '\n';
  27. }
  28. template<typename T, typename... Args>
  29. void err(istream_iterator<string> it, T a, Args... args) {
  30.     cerr << " [ " <<  *it << " : " << a  << " ] "<< ' ';
  31.     err(++it, args...);
  32. }
  33. const int N = 2005;
  34. vector <string> mat;
  35. vector <vector <pair <int, int>>> pos;
  36. int n, m, mx_char;
  37. int mask = 0;
  38. struct solution {
  39.    int xa, ya, xb, yb;
  40. };
  41. solution hash_sol;
  42. bool hash_ok;
  43. vector <solution> sol;
  44.  
  45. int dx[] = {1, 0, -1, 0};
  46. int dy[] = {0, 1, 0, -1};
  47. inline bool is_valid(int xx, int yy) {
  48.    return xx >= 0 && yy >= 0 && xx < n && yy < m;
  49. }
  50.  
  51. void init() {
  52.    mask = 0;
  53.    mx_char = -1;
  54.    hash_sol = {-1, -1, -1, -1};
  55.    hash_ok = false;
  56.    pos.assign(26, vector <pair <int,int>>());
  57.    sol.clear();
  58.    mat.clear();
  59. }
  60.  
  61. void read() {
  62.    cin >> n >> m;
  63.    string st;
  64.    for (int i = 0; i < n; ++i) {
  65.       cin >> st;
  66.       mat.push_back(st);
  67.       assert((int)st.size() == m);
  68.  
  69.       for (int j = 0; j < m; ++j) {
  70.          if (mat[i][j] == '.') continue;
  71.          char ch = mat[i][j];
  72.          mx_char = max(mx_char, int(ch - 'a'));
  73.          pos[int(ch-'a')].push_back(pair <int,int>(i,j));
  74.          mask |= (1 << int(ch - 'a'));
  75.       }
  76.    }
  77. }
  78.  
  79. void solve(int tc) {
  80.    bool ok = true;
  81.  
  82.    for (int i = mx_char; i >= 0 && ok; --i) {
  83.       if (mask & (1 << i)) { // present
  84.          //find direction
  85.  
  86.          int xx = pos[i][0].x, yy = pos[i][0].y;
  87.          int sol_len = 1;
  88.  
  89.          int this_dir = -1;
  90.          for (int dir = 0; dir < 4; ++dir) {
  91.             int X = xx + dx[dir], Y = yy + dy[dir];
  92.             while (is_valid(X, Y) && (mat[X][Y] == '#' || mat[X][Y] == char(i + 'a'))) {
  93.                if (mat[X][Y] == char(i + 'a')) this_dir = dir;
  94.                X = X + dx[dir], Y = Y + dy[dir];
  95.             }
  96.             if (this_dir != -1) break;
  97.          }
  98.          //change all to '#'
  99.  
  100.          mat[xx][yy] = '#';
  101.          if (this_dir != -1) {
  102.             int X = xx + dx[this_dir], Y = yy + dy[this_dir];
  103.             while (is_valid(X, Y) && (mat[X][Y] == '#' || mat[X][Y] == char(i + 'a'))) {
  104.                ++sol_len;
  105.                mat[X][Y] = '#';
  106.                X = X + dx[this_dir], Y = Y + dy[this_dir];
  107.             }
  108.          }
  109.          //check if something left
  110.          for (auto le : pos[i]) {
  111.             if (mat[le.x][le.y] != '#') {
  112.                ok = false;
  113.                break;
  114.             }
  115.          }
  116.          //store solution
  117.          if (this_dir == -1) {
  118.             sol.push_back({xx, yy, xx, yy});
  119.             hash_sol = {xx, yy, xx, yy};
  120.          }
  121.          else {
  122.             sol.push_back({xx, yy, xx + dx[this_dir]*(sol_len-1), yy + dy[this_dir]*(sol_len-1)});
  123.             hash_sol = {xx, yy, xx + dx[this_dir]*(sol_len-1), yy + dy[this_dir]*(sol_len-1)};
  124.          }
  125.       }
  126.       else { // not present
  127.          sol.push_back(hash_sol);
  128.       }
  129.    }
  130.    reverse(sol.begin(), sol.end());
  131.  
  132.    if (ok) {
  133.       cout << "YES\n";
  134.       cout << sol.size() << '\n';
  135.       for (int i = 0; i < (int)sol.size(); ++i) {
  136.          cout << sol[i].xa+1 << ' ' << sol[i].ya+1 << ' ' << sol[i].xb+1 << ' ' << sol[i].yb+1 << '\n';
  137.       }
  138.    }
  139.    else {
  140.       cout << "NO\n";
  141.    }
  142. }
  143.  
  144. signed main() {
  145.    IOS; PREC;
  146.    int tc;
  147.    cin >> tc;
  148.    for (int i = 1; i <= tc; ++i) {
  149.       init();
  150.       read();
  151.       solve(i);
  152.    }
  153.    return EXIT_SUCCESS;
  154. }
Add Comment
Please, Sign In to add comment