Advertisement
Guest User

Optimal Solution for Googla Hash Code 2016 Practice

a guest
Feb 8th, 2016
361
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.34 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. #include <glpk.h>
  4.  
  5. using namespace std;
  6.  
  7. #define FORE(it,c)  for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
  8. #define FOR(i,a,b)  for(int i=(a);i<(b);++i)
  9. #define REP(i,a)    FOR(i,0,a)
  10. #define ZERO(m)    memset(m,0,sizeof(m))
  11. #define ALL(x)      x.begin(),x.end()
  12. #define PB          push_back
  13. #define S          size()
  14. #define LL          long long
  15. #define ULL        unsigned long long
  16. #define LD          long double
  17. #define MP          make_pair
  18. #define X          first
  19. #define Y          second
  20. #define VC          vector
  21. #define PII        pair <int, int>
  22. #define VI          VC < int >
  23. #define VVI        VC < VI >
  24. #define VD          VC < double >
  25. #define VVD        VC < VD >
  26. #define VS          VC < string >
  27. #define DB(a)      cerr << #a << ": " << (a) << endl;
  28.  
  29. template<class T> void print(VC < T > v) {cerr << "[";if (v.S) cerr << v[0];FOR(i, 1, v.S) cerr << ", " << v[i];cerr << "]\n";}
  30. template<class T> string i2s(T x) {ostringstream o; o << x; return o.str(); }
  31. VS splt(string s, char c = ' ') {VS all; int p = 0, np; while (np = s.find(c, p), np >= 0) {if (np != p) all.PB(s.substr(p, np - p)); p = np + 1;} if (p < s.S) all.PB(s.substr(p)); return all;}
  32.  
  33. const int MAX_DIM = 1024;
  34.  
  35. int bmp[MAX_DIM][MAX_DIM];
  36. int cur[MAX_DIM][MAX_DIM];
  37.  
  38. int n, m;
  39.  
  40. int greedy() {
  41.    
  42. }
  43.  
  44. glp_prob *lp;
  45.  
  46. void lpcallback(glp_tree *tree, void *info) {
  47.     if (glp_ios_reason(tree) == GLP_IBINGO) {
  48.         DB(glp_mip_obj_val(lp));
  49.     }
  50. }
  51.  
  52. int dr[] = {0, 1, 1, 1};
  53. int dc[] = {1, -1, 0, 1};
  54.  
  55. bool ok(int r, int c) {
  56.     return r >= 0 && r < n && c >= 0 && c < m && cur[r][c];
  57. }
  58.  
  59. VS operations;
  60. VI pixels[MAX_DIM][MAX_DIM];
  61. VS lpsolve() {
  62.     REP(r0, n) REP(c0, m) if (ok(r0, c0)) {
  63.         int size = 1;
  64.         while (true) {
  65.             bool good = true;
  66.             FOR(i, -size, size+1) good &= ok(r0-size,c0+i);
  67.             FOR(i, -size, size+1) good &= ok(r0+size,c0+i);
  68.             FOR(i, -size, size+1) good &= ok(r0+i,c0-size);
  69.             FOR(i, -size, size+1) good &= ok(r0+i,c0+size);
  70.             if (!good) break;
  71.             size++;
  72.         }
  73.         size--;
  74.         // if (size == 0) continue;
  75.         FOR(r, r0-size, r0+size+1) FOR(c, c0-size, c0+size+1)
  76.             pixels[r][c].PB(operations.S);
  77.         char s[1000];
  78.         sprintf(s, "PAINT_SQUARE %d %d %d", r0, c0, size);
  79.         operations.PB(s);
  80.     }
  81.     DB(operations.S);
  82.    
  83.     REP(r0, n) REP(c0, m) if (ok(r0, c0) && !ok(r0-1, c0)) {
  84.         int len = 0;
  85.         pixels[r0][c0].PB(operations.S);
  86.         while (ok(r0+len+1, c0)) {
  87.             pixels[r0+len+1][c0].PB(operations.S);
  88.             len++;
  89.         }
  90.         // if (len == 0) continue;
  91.         char s[1000];
  92.         sprintf(s, "PAINT_LINE %d %d %d %d", r0, c0, r0+len, c0);
  93.         operations.PB(s);
  94.     }
  95.     DB(operations.S);
  96.    
  97.     REP(r0, n) REP(c0, m) if (ok(r0, c0) && !ok(r0, c0-1)) {
  98.         int len = 0;
  99.         pixels[r0][c0].PB(operations.S);
  100.         while (ok(r0, c0+len+1)) {
  101.             pixels[r0][c0+len+1].PB(operations.S);
  102.             len++;
  103.         }
  104.         // if (len == 0) continue;
  105.         char s[1000];
  106.         sprintf(s, "PAINT_LINE %d %d %d %d", r0, c0, r0, c0+len);
  107.         operations.PB(s);
  108.     }
  109.    
  110.     DB(operations.S);
  111.    
  112.     VI lpr, lpc;
  113.     VD lpv;
  114.    
  115.     int rows = 0;
  116.     lpr.PB(0);
  117.     lpc.PB(0);
  118.     lpv.PB(0);
  119.     REP(r, n) REP(c, m) if (cur[r][c]) {
  120.         REP(i, pixels[r][c].S) {
  121.             lpr.PB(rows + 1);
  122.             lpc.PB(pixels[r][c][i] + 1);
  123.             lpv.PB(1.0);
  124.         }
  125.         rows++;
  126.        
  127.     }
  128.  
  129.     glp_term_out(GLP_OFF);
  130.    
  131.     lp = glp_create_prob();
  132.     glp_set_prob_name(lp, "sample");
  133.     glp_set_obj_dir(lp, GLP_MIN);
  134.    
  135.     glp_add_rows(lp, rows);
  136.     REP(i, rows) glp_set_row_bnds(lp, i + 1, GLP_LO, 1.0, 0.0);
  137.    
  138.     glp_add_cols(lp, operations.S);
  139.     REP(i, operations.S) {
  140.         glp_set_col_bnds(lp, i + 1, GLP_DB, 0.0, 1.0);
  141.         glp_set_obj_coef(lp, i + 1, 1.0);
  142.         glp_set_col_kind(lp, i + 1, GLP_BV);
  143.     }
  144.    
  145.     glp_load_matrix(lp, lpr.S - 1, &lpr[0], &lpc[0], &lpv[0]);
  146.    
  147.     glp_iocp parm;
  148.     glp_init_iocp(&parm);
  149.     parm.presolve = GLP_ON;
  150.     parm.cb_func = lpcallback;
  151.     parm.cb_info = NULL;
  152.     glp_intopt(lp, &parm);
  153.    
  154.     DB(glp_mip_obj_val(lp));
  155.    
  156.     VS rv;
  157.     REP(i, operations.S) {
  158.         if (glp_mip_col_val(lp, i + 1)) rv.PB(operations[i]);
  159.     }
  160.    
  161.     glp_delete_prob(lp);
  162.    
  163.     return rv;
  164. }
  165.  
  166. bool validate(VS v) {
  167.     memcpy(cur, bmp, sizeof(int)*MAX_DIM*n);
  168.    
  169.     bool error = false;
  170.    
  171.     REP(i, v.S) {
  172.         char s[100];
  173.         int r0 = -1, r1 = -1, c0 = -1, c1 = -1;
  174.         sscanf(v[i].c_str(), "%s %d %d %d %d", s, &r0, &c0, &r1, &c1);
  175.        
  176.         if (c1 == -1) {
  177.             int size = r1;
  178.             c1 = c0 + size;
  179.             r1 = r0 + size;
  180.             r0 = r0 - size;
  181.             c0 = c0 - size;
  182.         }
  183.        
  184.         FOR(r, r0, r1+1) FOR(c, c0, c1+1) {
  185.             if (bmp[r][c] == 0) {
  186.                 error = true;
  187.                 cerr << "Error in: " << v[i] << endl;
  188.             }
  189.             cur[r][c] = 0;         
  190.         }
  191.     }
  192.    
  193.     int rem = 0;
  194.     REP(r, n) REP(c, m) rem += cur[r][c];
  195.    
  196.     if (rem) {
  197.         REP(r, n) {
  198.             REP(c, m) cout << (char)(cur[r][c] ? '#' : '.');
  199.             cout << endl;
  200.         }
  201.         DB(rem);
  202.     }
  203.    
  204.     return rem == 0 || error;
  205. }
  206.  
  207. int main() {
  208.     cin >> n >> m;
  209.     REP(i, n) {
  210.         string s;
  211.         cin >> s;
  212.         REP(j, m) bmp[i][j] = s[j] == '#';
  213.     }
  214.    
  215.     memcpy(cur, bmp, sizeof(int)*MAX_DIM*n);
  216.     VS clears;
  217.     // FOR(r, 1, n - 1) FOR(c, 1, m - 1) if (!ok(r, c) && ok(r - 1, c) && ok(r + 1, c) && ok(r, c - 1) && ok(r, c + 1)) {
  218.         // bmp[r][c] = 1;
  219.         // char s[100];
  220.         // sprintf(s, "CLEAR %d %d", r + 1, c + 1);
  221.         // clears.PB(s);
  222.     // }
  223.     DB(clears.S);
  224.     memcpy(cur, bmp, sizeof(int)*MAX_DIM*n);
  225.    
  226.     VS rv = lpsolve();
  227.    
  228.     DB(validate(rv));
  229.    
  230.     DB(clears.S);
  231.     rv.insert(rv.end(), ALL(clears));
  232.     DB(rv.S);
  233.    
  234.     cout << rv.S << endl;
  235.     REP(i, rv.S) cout << rv[i] << endl;
  236. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement