Guest User

rectangles.cpp

a guest
May 19th, 2018
565
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.77 KB | None | 0 0
  1. /*
  2.     File: rectangles.cpp
  3.    
  4.     Compile command: g++ -O2 -std=c++17 -Wall -Wextra -pedantic rectangles.cpp -o rectangles.o
  5.    
  6.     Example:
  7.     4 3
  8.     ###
  9.     #.#
  10.     #.#
  11.     ###
  12.    
  13.     Output: 1
  14. */
  15.  
  16.  
  17. #pragma GCC diagnostic ignored "-Wunused-result"
  18. #include <stdio.h>
  19. #include <cassert>
  20. #include <cstdlib>
  21. #include <ctime>
  22. #include <cstdint>
  23.  
  24. const bool TIMING = false;
  25.  
  26. char getChar() {
  27.     static char buffer[1024*1024];
  28.     static int pos = 0;
  29.     static int size = 0;
  30.     if (pos == size) {
  31.         size = fread(buffer, 1, 1024*1024, stdin);
  32.         pos = 0;
  33.     }
  34.     if (pos == size) {
  35.         return EOF;
  36.     }
  37.     return buffer[pos++];
  38. }
  39.  
  40. void putChar(char c) {
  41. // c == -1 or size == sizeof(buffer) --> flush buffer
  42.     static char buffer[1024*1024];
  43.     static int size = 0;
  44.     if (size == 1024 * 1024 || c == -1) {
  45.         fwrite(buffer, 1, size, stdout);
  46.         size = 0;
  47.     }
  48.     buffer[size++] = c;
  49. }
  50.  
  51. int getInt(bool& success) {
  52.     char c = '?';
  53.     while (!(c == '-' || ('0' <= c && c <= '9') || c == EOF)) {
  54.         c = getChar();
  55.     }
  56.     if (c == EOF) {
  57.         success = false;
  58.         return 0;
  59.     }
  60.     int sign = 1;
  61.     if (c == '-') {
  62.         sign *= -1;
  63.         c = getChar();
  64.     }
  65.     int answ = 0;
  66.     while ('0' <= c && c <= '9') {
  67.         (answ *= 10) += (c-'0');
  68.         c = getChar();
  69.     }
  70.     success = true;
  71.     return sign * answ;
  72. }
  73.  
  74. void putStr(const char *buf) {
  75.     for (auto it = buf; *it != '\0'; ++it) {
  76.         putChar(*it);
  77.     }
  78. }
  79.  
  80. void putInt(int number) {
  81.     static char buf[12];
  82.     sprintf(buf, "%d", number);
  83.     putStr(buf);
  84. }
  85.  
  86. void putInt(long long number) {
  87.     static char buf[24];
  88.     sprintf(buf, "%lld", number);
  89.     putStr(buf);
  90. }
  91.  
  92. int main() {
  93.     double total_time = clock();
  94.     while (true) {
  95.         bool flag;
  96.         int nRows = getInt(flag); // input number of rows of array
  97.         int nCols = getInt(flag); // input number of cols of array
  98.         if (!flag) {
  99.             break;
  100.         }
  101.         static char arr[350][350]; // arr[r][c] = 1 if '#' and arr[r][c] = 0 if '.'
  102.         for (int row = 0; row < nRows; ++row) {
  103.             for (int col = 0; col < nCols; ++col) {
  104.                 char c = getChar();
  105.                 arr[row][col] = (c == '#');
  106.             }
  107.             char c = getChar();
  108.             assert(c == '\n' || (c == EOF && row == nRows-1));
  109.         }
  110.        
  111.         static int maxLenDown[351][350]; // maxLenDown[r][c] = len of max sequence of '#' from pos (row, col) in side of increasing row
  112.         for (int row = 0; row <= nRows; ++row) {
  113.             for (int col = 0; col < nCols; ++col) {
  114.                 maxLenDown[row][col] = 0;
  115.             }
  116.         }
  117.        
  118.         for (int row = nRows-1; row >= 0; --row) {
  119.             for (int col = 0; col < nCols; ++col) {
  120.                 if (arr[row][col]) {
  121.                     maxLenDown[row][col] = 1 + maxLenDown[row+1][col];
  122.                 }
  123.             }
  124.         }        
  125.        
  126.         static int bin_2[351]; // bin_2[i] = C(i, 2);
  127.         for (int i = 0; i < 351; ++i) {
  128.             bin_2[i] = i * (i-1) / 2;
  129.         }
  130.        
  131.         // Calculate all rectangles with top side = row1 and bottom side = row2 (rectangles with width = 2 will also be counted)
  132.         long long answ = 0;
  133.         for (int row1 = 0; row1 < nRows-2; ++row1) {
  134.             int temp = 0;
  135.             for (int row2 = row1+2; row2 < nRows; ++row2) {
  136.                 int len = 0;
  137.                 for (int col = 0; col < nCols; ++col) { // TO DO: speed up this cycle
  138.                     if (arr[row1][col] & arr[row2][col]) {
  139.                         len += (maxLenDown[row1][col] >= row2-row1+1);
  140.                     } else {
  141.                         temp += bin_2[len];
  142.                         len = 0;
  143.                     }
  144.                 }
  145.                 temp += bin_2[len];
  146.             }
  147.             answ += temp;
  148.         }
  149.         // Decreasing number of rectangles with width = 2
  150.         for (int col1 = 0; col1 < nCols-1; ++col1) {
  151.             const int col2 = col1+1;
  152.             int len = 0;
  153.             for (int row = 0; row < nRows; ++row) {
  154.                 if (arr[row][col1] & arr[row][col2]) {
  155.                     ++len;
  156.                 } else {
  157.                     if (len >= 3) {
  158.                         answ -= bin_2[len-1];
  159.                     }
  160.                     len = 0;
  161.                 }
  162.             }
  163.             if (len >= 3) {
  164.                 answ -= bin_2[len-1];
  165.             }
  166.         }
  167.  
  168.         putInt(answ);
  169.         putChar('\n');
  170.     }
  171.     putChar(-1);
  172.    
  173.     if (TIMING) {
  174.         total_time = (clock() - total_time) / CLOCKS_PER_SEC;
  175.         printf("----------------\ntime = %0.3f\n", total_time);
  176.     }
  177.    
  178.     return 0;
  179. }
Advertisement
Add Comment
Please, Sign In to add comment