Problem p01427 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>

using namespace std;

#define reps(i, f, n) for (int i = f; i < int(n); i++)
#define rep(i, n) reps(i, 0, n)
#define pb push_back

const int W = 666;
const int INF = 1000000007;
int h, w;
vector<string> board;

bool input() {
  cin >> h >> w;
  board.clear();
  rep(i, h) {
    string s;
    cin >> s;
    board.pb(s);
  }
  return true;
}

int gcd(int n, int m) { return (n % m) ? gcd(m, n % m) : m; }

int isBlock(char c) {
  if (c == '#')
    return 1;
  return 0;
}

int getState(int y, int x) {
  int ret = 0;
  ret += (1 << 0) * isBlock(board[y][x - 1]);
  ret += (1 << 1) * isBlock(board[y][x]);
  ret += (1 << 2) * isBlock(board[y - 1][x - 1]);
  ret += (1 << 3) * isBlock(board[y - 1][x]);
  return ret;
}

int cup[16];
int cdown[16];

int _cup(int state) {
  switch (state) {
  case 0:
    return 0;
  case 1:
    return 2;
  case 2:
    return 1;
  case 3:
    return 1;
  case 4:
    return 1;
  case 5:
    return 1;
  case 6:
    return 2;
  case 7:
    return 0;
  case 8:
    return 0;
  case 9:
    return 2;
  case 10:
    return 1;
  case 11:
    return 1;
  case 12:
    return 1;
  case 13:
    return 1;
  case 14:
    return 2;
  case 15:
    return 0;
  }
  return -INF;
}

int _cdown(int state) {
  switch (state) {
  case 0:
    return 0;
  case 1:
    return 0;
  case 2:
    return 1;
  case 3:
    return 1;
  case 4:
    return 1;
  case 5:
    return 1;
  case 6:
    return 2;
  case 7:
    return 2;
  case 8:
    return 2;
  case 9:
    return 2;
  case 10:
    return 1;
  case 11:
    return 1;
  case 12:
    return 1;
  case 13:
    return 1;
  case 14:
    return 0;
  case 15:
    return 0;
  }
  return -INF;
}

void setCount() {
  rep(i, 16) cup[i] = _cup(i);
  rep(i, 16) cdown[i] = _cdown(i);
}

int getCountUp(int y, int x) {
  int state = getState(y, x);

  return cup[state];
}

int getCountDown(int y, int x) {

  int state = getState(y, x);

  return cdown[state];
}

int splitCount(int y, int x) {

  int countUp = 0;
  int countDown = 0;

  double dy = (double)y / x;
  double dx = (double)x / y;
  /*
  reps(i,1,w+1){
  double dy = (double)y/x;
  if(i%x==0){
      int ny = y*(i/x);
      int nx = i;
      if(ny>h)break;

      int dup = getCountUp(ny,nx);
      int ddown = getCountDown(ny,nx);

      if(x==2 && y==1 || true){
          //printf("nx=%d  ny=%d,  dup=%d  ddown=%d\\n",nx,ny,dup,ddown);
      }

      countUp += dup;
      countDown += ddown;
  }
}
*/

  for (int i = 1; i * x <= w; i++) {
    int ny = y * i;
    int nx = x * i;
    if (ny > h)
      break;

    int dup = getCountUp(ny, nx);
    int ddown = getCountDown(ny, nx);

    countUp += dup;
    countDown += ddown;
  }

  reps(i, 1, w + 1) {
    if (i % x != 0) {
      double ny = dy * i;

      int nh = (int)ny;
      if (nh > h)
        break;

      char left = board[nh][i - 1];
      char right = board[nh][i];

      if (left != right) {
        countUp++;
        countDown++;
      }
    }
  }
  reps(i, 1, h + 1) {

    if (i % y != 0) {

      int nh = (int)(dx * i);
      if (nh > w)
        break;

      char left = board[i - 1][nh];
      char right = board[i][nh];

      if (left != right) {
        countUp++;
        countDown++;
      }
    }
  }

  int ans1 = (countUp + 1) / 2 + 1;
  int ans2 = (countDown + 1) / 2 + 1;

  // printf("x=%d y=%d  up=%d  down=%d\\n",x,y,countUp, countDown);

  return max(ans1, ans2);
}

void addBanpei() {
  reverse(board.begin(), board.end());
  rep(i, board.size()) { board[i] += "."; }
  string tmp = "";
  rep(i, w + 1) tmp += ".";
  board.pb(tmp);
}

void solve() {

  addBanpei();
  setCount();

  int ans = 0;
  reps(i, 1, h + 1) {
    reps(j, 1, w + 1) {
      if (gcd(i, j) == 1) {
        int sp = splitCount(i, j);
        ans = max(ans, sp);
      }
    }
  }

  cout << ans << endl;
}

int main() {
  input();
  solve();
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>

using namespace std;

#define reps(i, f, n) for (int i = f; i < int(n); i++)
#define rep(i, n) reps(i, 0, n)
#define pb push_back

const int W = 666;
const int INF = 1000000007;
int h, w;
vector<string> board;

bool input() {
  cin >> h >> w;
  board.clear();
  rep(i, h) {
    string s;
    cin >> s;
    board.pb(s);
  }
  return true;
}

int gcd(int n, int m) { return (n % m) ? gcd(m, n % m) : m; }

int isBlock(char c) {
  if (c == '#')
    return 1;
  return 0;
}

int getState(int y, int x) {
  int ret = 0;
  ret += (1 << 0) * isBlock(board[y][x - 1]);
  ret += (1 << 1) * isBlock(board[y][x]);
  ret += (1 << 2) * isBlock(board[y - 1][x - 1]);
  ret += (1 << 3) * isBlock(board[y - 1][x]);
  return ret;
}

int cup[16];
int cdown[16];

int _cup(int state) {
  switch (state) {
  case 0:
    return 0;
  case 1:
    return 2;
  case 2:
    return 1;
  case 3:
    return 1;
  case 4:
    return 1;
  case 5:
    return 1;
  case 6:
    return 2;
  case 7:
    return 0;
  case 8:
    return 0;
  case 9:
    return 2;
  case 10:
    return 1;
  case 11:
    return 1;
  case 12:
    return 1;
  case 13:
    return 1;
  case 14:
    return 2;
  case 15:
    return 0;
  }
  return -INF;
}

int _cdown(int state) {
  switch (state) {
  case 0:
    return 0;
  case 1:
    return 0;
  case 2:
    return 1;
  case 3:
    return 1;
  case 4:
    return 1;
  case 5:
    return 1;
  case 6:
    return 2;
  case 7:
    return 2;
  case 8:
    return 2;
  case 9:
    return 2;
  case 10:
    return 1;
  case 11:
    return 1;
  case 12:
    return 1;
  case 13:
    return 1;
  case 14:
    return 0;
  case 15:
    return 0;
  }
  return -INF;
}

void setCount() {
  rep(i, 16) cup[i] = _cup(i);
  rep(i, 16) cdown[i] = _cdown(i);
}

int getCountUp(int y, int x) {
  int state = getState(y, x);

  return cup[state];
}

int getCountDown(int y, int x) {

  int state = getState(y, x);

  return cdown[state];
}

int splitCount(int y, int x) {

  int countUp = 0;
  int countDown = 0;

  reps(i, 1, w + 1) {
    double dy = (double)y / x;
    if (i % x == 0) {
      int ny = y * (i / x);
      int nx = i;
      if (ny > h)
        break;

      int dup = getCountUp(ny, nx);
      int ddown = getCountDown(ny, nx);

      if (x == 2 && y == 1 || true) {
        // printf("nx=%d  ny=%d,  dup=%d  ddown=%d\\n",nx,ny,dup,ddown);
      }

      countUp += dup;
      countDown += ddown;
    }
  }

  double dy = (double)y / x;
  double dx = (double)x / y;

  reps(i, 1, w + 1) {
    if (i % x != 0) {
      double ny = dy * i;

      int nh = (int)ny;
      if (nh > h)
        break;

      char left = board[nh][i - 1];
      char right = board[nh][i];

      if (left != right) {
        countUp++;
        countDown++;
      }
    }
  }
  reps(i, 1, h + 1) {

    if (i % y != 0) {

      int nh = (int)(dx * i);
      if (nh > w)
        break;

      char left = board[i - 1][nh];
      char right = board[i][nh];

      if (left != right) {
        countUp++;
        countDown++;
      }
    }
  }

  int ans1 = (countUp + 1) / 2 + 1;
  int ans2 = (countDown + 1) / 2 + 1;

  // printf("x=%d y=%d  up=%d  down=%d\\n",x,y,countUp, countDown);

  return max(ans1, ans2);
}

void addBanpei() {
  reverse(board.begin(), board.end());
  rep(i, board.size()) { board[i] += "."; }
  string tmp = "";
  rep(i, w + 1) tmp += ".";
  board.pb(tmp);
}

void solve() {

  addBanpei();
  setCount();

  int ans = 0;
  reps(i, 1, h + 1) {
    reps(j, 1, w + 1) {
      if (gcd(i, j) == 1) {
        int sp = splitCount(i, j);
        ans = max(ans, sp);
      }
    }
  }

  cout << ans << endl;
}

int main() {
  input();
  solve();
}