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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <iostream>
#include <queue>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define inf (1 << 29)
#define MAX (1 << 20)
using namespace std;

struct P {
  int state, cost;
  P(int state = inf, int cost = inf) : state(state), cost(cost) {}
  bool operator<(const P &a) const { return cost > a.cost; }
};

short mincost[MAX];
short mincost5[1 << 5];
int rect[5][5][5][5];

void init() {
  rep(i, MAX) mincost[i] = 25;
  rep(i, 5) rep(j, 5) rep(k, 5) rep(l, 5) rect[i][j][k][l] = 0;
}

void makeRect() {
  rep(y1, 5) rep(x1, 5)             // top-left
      REP(y2, y1, 5) REP(x2, x1, 5) // bottom-right
      REP(y, y1, y2 + 1) REP(x, x1, x2 + 1) rect[y1][x1][y2][x2] |=
      (1 << (y * 5 + x));
}

void makeMincost() {
  mincost[0] = 0;
  priority_queue<P> que;
  que.push(P(0, 0));

  while (!que.empty()) {
    P p = que.top();
    que.pop();

    rep(y1, 4) rep(x1, 5) REP(y2, y1, 4) REP(x2, x1, 5) {
      int nstate = p.state ^ rect[y1][x1][y2][x2];
      if (mincost[nstate] > p.cost + 1) {
        mincost[nstate] = p.cost + 1;
        que.push(P(nstate, p.cost + 1));
      }
    }
  }
}

void print(int f) {
  bitset<25> ff(f);
  rep(i, 5) {
    cout << i << " : ";
    rep(j, 5) { cout << ff[i * 5 + j] << " "; }
    cout << endl;
  }
  cout << endl;
}

void dfs(int state, int cur, int cost, int &ans) {
  if (state < (1 << 20))
    ans = min(ans, cost + mincost[state]);
  if (cost >= ans)
    return;
  if (cur >= 3)
    return;

  rep(y1, 5) rep(x1, 5) REP(x, x1, 5) {
    int nstate = state ^ rect[y1][x1][4][x];
    int nstate5 = (nstate >> 20);

    // cout << "ns = " << endl;
    // print(nstate);

    dfs(nstate, cur + 1, cost + 1, ans);
  }
}

int compute(int field) {
  int bf = (field >> 20);
  int nfield = field & (1 << 20) - 1;
  int ret = __builtin_popcount(bf) + mincost[nfield];

  // cout << "start dfs" << endl;
  dfs(field, 0, 0, ret);
  // cout << "end dfs" << endl;
  // cout << "ret = " << ret << endl;
  return ret;
}

int main() {
  int n, field;
  init();
  makeRect();
  /*
  rep(y,3)
    rep(x,3)
    {
      bitset<20> b(rect[0][0][y][x]);
      cout << "(" << x << "," << y << ") " << b << endl;
    }
  */
  // cout << "finish -- makeRect" << endl;
  makeMincost();
  // cout << "finish -- makeMincost" <<endl;

  while (cin >> n, n) {
    field = 0;
    {
      char c;
      rep(y, n) rep(x, n) {
        cin >> c;
        if (c == '1')
          field |= (1 << (y * 5 + x));
      }
      int cnt = (n <= 4 ? mincost[field] : compute(field));
      rep(i, cnt) cout << "myon";
      cout << endl;
    }
  }
  return 0;
}

/*
struct P
{
  int state,cost;
  P(int state = inf,int cost = inf):state(state),cost(cost){}
  bool operator < (const P& a)const
  {
    return cost > a.cost;
  }
};

int n;
short mincost[5][MAX];
int rect[5][5][5][5][5];
int lim;

void makeRect()
{
  rep(i,5)rep(j,5)rep(k,5)rep(l,5)rep(m,5)rect[i][j][k][l][m] = 0;

  rep(depth,5)
    {
      rep(y1,depth+1)rep(x1,depth+1)
        REP(y2,y1,depth+1)REP(x2,x1,depth+1)
          REP(y,y1,y2+1)REP(x,x1,x2+1)
          {
            rect[depth][y1][x1][y2][x2] |= (1<<(y*(depth+1)+x));
          }
    }

}



void compute(int N)
{
  rep(i,(1<<(N*N)))mincost[N-1][i] = N*N+1;
  mincost[N-1][0] = 0;
  cout << "N = "<< N << endl;
  rep(state,(1<<(N*N)))
    {
      if(mincost[N-1][state] == N*N+1)continue;
      rep(y1,N)rep(x1,N)
        REP(y2,y1,N)REP(x2,x1,N)
        {
          int nstate = state ^ rect[N-1][y1][x1][y2][x2];
          mincost[N-1][nstate] = min(mincost[N-1][nstate],
                                     (short)(mincost[N-1][state]+1));
        }
    }
}

int main()
{

  makeRect();
  cout << "finish --- make rectangle" << endl;

  compute(1);
  compute(2);
  compute(3);
  compute(4);
  //compute(5);
  cout << "-------------" << endl;
  while(cin >> n,n)
    {
      lim = (1<<n);

      int field = 0,c;
      rep(y,n)rep(x,n)
        {
          cin >> c;
          if(c)field |= (1<<(n*y + x));
        }
      bitset<25> bi(field);
      cout << "field " << bi << endl;

      cout << mincost[n-1][field] << endl;

    }
  return 0;
}
*/

/*
 REP(y,1,3)
   {
     REP(x,1,3)
       {
         cout << "y = " << y << " x = " << x << endl;
         bitset<10> bit(rect[2][1][1][y][x]);
         cout << "***" << bit << "***" << endl;
       }
   }
 */

/*
void compute(int N)
{
  rep(j,(1<<(N*N)))mincost[N-1][j] = N*N+1;
  mincost[N-1][0] = 0;
  //queue<P> que;
  priority_queue<P> que;
  que.push(P(0,0));

  cout << "N = " << N << endl;
  while(!que.empty())
    {
      //P p = que.front(); que.pop();
      P p = que.top(); que.pop();
      //bitset<5> bb(p.state);
      //cout << "cur = " << bb << " cost = " << p.cost << endl;

      rep(y1,N)
        {
          rep(x1,N)
            {
              REP(y2,y1,N)
                {
                  REP(x2,x1,N)
                    {
                      //bitset<5> re(rect[N-1][y1][x1][y2][x2]);
                      //cout << "rect["<<y1<<"]["<<x1<<"]["<<y2<<"]["<<x2<<"] =
" << re << endl; int nstate = p.state ^ rect[N-1][y1][x1][y2][x2];
                      if(mincost[N-1][nstate] > p.cost + 1)
                        {
                          bitset<5> nex(nstate);
                          //cout << "go to next = " << nex << " cost = " <<
p.cost+1 << endl;
                          //cout << endl;
                          mincost[N-1][nstate] = p.cost + 1;
                          que.push(P(nstate,p.cost+1));
                        }
                      //else cout << re << " is bad case because " <<
mincost[N-1][nstate] << " !> " << p.cost+1<< endl << endl;
                    }
                }
            }
        }

    }

}
*/

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <iostream>
#include <queue>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define inf (1 << 29)
#define MAX (1 << 20)
using namespace std;

struct P {
  int state, cost;
  P(int state = inf, int cost = inf) : state(state), cost(cost) {}
  bool operator<(const P &a) const { return cost > a.cost; }
};

short mincost[MAX];
short mincost5[1 << 5];
int rect[5][5][5][5];

void init() {
  rep(i, MAX) mincost[i] = 25;
  rep(i, 5) rep(j, 5) rep(k, 5) rep(l, 5) rect[i][j][k][l] = 0;
}

void makeRect() {
  rep(y1, 5) rep(x1, 5)             // top-left
      REP(y2, y1, 5) REP(x2, x1, 5) // bottom-right
      REP(y, y1, y2 + 1) REP(x, x1, x2 + 1) rect[y1][x1][y2][x2] |=
      (1 << (y * 5 + x));
}

void makeMincost() {
  mincost[0] = 0;
  priority_queue<P> que;
  que.push(P(0, 0));

  while (!que.empty()) {
    P p = que.top();
    que.pop();

    rep(y1, 4) rep(x1, 5) REP(y2, y1, 4) REP(x2, x1, 5) {
      int nstate = p.state ^ rect[y1][x1][y2][x2];
      if (mincost[nstate] > p.cost + 1) {
        mincost[nstate] = p.cost + 1;
        que.push(P(nstate, p.cost + 1));
      }
    }
  }
}

void print(int f) {
  bitset<25> ff(f);
  rep(i, 5) {
    cout << i << " : ";
    rep(j, 5) { cout << ff[i * 5 + j] << " "; }
    cout << endl;
  }
  cout << endl;
}

void dfs(int state, int cur, int cost, int &ans) {
  if (state < (1 << 20))
    ans = min(ans, cost + mincost[state]);
  if (cost >= ans)
    return;
  if (cur >= 5)
    return;

  rep(y1, 5) rep(x1, 5) REP(x, x1, 5) {
    int nstate = state ^ rect[y1][x1][4][x];
    int nstate5 = (nstate >> 20);

    // cout << "ns = " << endl;
    // print(nstate);

    dfs(nstate, cur + 1, cost + 1, ans);
  }
}

int compute(int field) {
  rep(i, (1 << 5)) mincost5[i] = 100;
  bitset<30> b(field), b2(field >> 20);
  // cout << "b = " << b << endl;
  // cout << "b2 = " << b2 << endl;
  mincost5[(field >> 20)] = 0;
  int ret = 5;
  // cout << "start dfs" << endl;
  dfs(field, 0, 0, ret);
  // cout << "end dfs" << endl;
  // cout << "ret = " << ret << endl;
  return ret;
}

int main() {
  int n, field;
  init();
  makeRect();
  /*
  rep(y,3)
    rep(x,3)
    {
      bitset<20> b(rect[0][0][y][x]);
      cout << "(" << x << "," << y << ") " << b << endl;
    }
  */
  // cout << "finish -- makeRect" << endl;
  makeMincost();
  // cout << "finish -- makeMincost" <<endl;

  while (cin >> n, n) {
    field = 0;
    {
      char c;
      rep(y, n) rep(x, n) {
        cin >> c;
        if (c == '1')
          field |= (1 << (y * 5 + x));
      }
      int cnt = (n <= 4 ? mincost[field] : compute(field));
      rep(i, cnt) cout << "myon";
      cout << endl;
    }
  }
  return 0;
}

/*
struct P
{
  int state,cost;
  P(int state = inf,int cost = inf):state(state),cost(cost){}
  bool operator < (const P& a)const
  {
    return cost > a.cost;
  }
};

int n;
short mincost[5][MAX];
int rect[5][5][5][5][5];
int lim;

void makeRect()
{
  rep(i,5)rep(j,5)rep(k,5)rep(l,5)rep(m,5)rect[i][j][k][l][m] = 0;

  rep(depth,5)
    {
      rep(y1,depth+1)rep(x1,depth+1)
        REP(y2,y1,depth+1)REP(x2,x1,depth+1)
          REP(y,y1,y2+1)REP(x,x1,x2+1)
          {
            rect[depth][y1][x1][y2][x2] |= (1<<(y*(depth+1)+x));
          }
    }

}



void compute(int N)
{
  rep(i,(1<<(N*N)))mincost[N-1][i] = N*N+1;
  mincost[N-1][0] = 0;
  cout << "N = "<< N << endl;
  rep(state,(1<<(N*N)))
    {
      if(mincost[N-1][state] == N*N+1)continue;
      rep(y1,N)rep(x1,N)
        REP(y2,y1,N)REP(x2,x1,N)
        {
          int nstate = state ^ rect[N-1][y1][x1][y2][x2];
          mincost[N-1][nstate] = min(mincost[N-1][nstate],
                                     (short)(mincost[N-1][state]+1));
        }
    }
}

int main()
{

  makeRect();
  cout << "finish --- make rectangle" << endl;

  compute(1);
  compute(2);
  compute(3);
  compute(4);
  //compute(5);
  cout << "-------------" << endl;
  while(cin >> n,n)
    {
      lim = (1<<n);

      int field = 0,c;
      rep(y,n)rep(x,n)
        {
          cin >> c;
          if(c)field |= (1<<(n*y + x));
        }
      bitset<25> bi(field);
      cout << "field " << bi << endl;

      cout << mincost[n-1][field] << endl;

    }
  return 0;
}
*/

/*
 REP(y,1,3)
   {
     REP(x,1,3)
       {
         cout << "y = " << y << " x = " << x << endl;
         bitset<10> bit(rect[2][1][1][y][x]);
         cout << "***" << bit << "***" << endl;
       }
   }
 */

/*
void compute(int N)
{
  rep(j,(1<<(N*N)))mincost[N-1][j] = N*N+1;
  mincost[N-1][0] = 0;
  //queue<P> que;
  priority_queue<P> que;
  que.push(P(0,0));

  cout << "N = " << N << endl;
  while(!que.empty())
    {
      //P p = que.front(); que.pop();
      P p = que.top(); que.pop();
      //bitset<5> bb(p.state);
      //cout << "cur = " << bb << " cost = " << p.cost << endl;

      rep(y1,N)
        {
          rep(x1,N)
            {
              REP(y2,y1,N)
                {
                  REP(x2,x1,N)
                    {
                      //bitset<5> re(rect[N-1][y1][x1][y2][x2]);
                      //cout << "rect["<<y1<<"]["<<x1<<"]["<<y2<<"]["<<x2<<"] =
" << re << endl; int nstate = p.state ^ rect[N-1][y1][x1][y2][x2];
                      if(mincost[N-1][nstate] > p.cost + 1)
                        {
                          bitset<5> nex(nstate);
                          //cout << "go to next = " << nex << " cost = " <<
p.cost+1 << endl;
                          //cout << endl;
                          mincost[N-1][nstate] = p.cost + 1;
                          que.push(P(nstate,p.cost+1));
                        }
                      //else cout << re << " is bad case because " <<
mincost[N-1][nstate] << " !> " << p.cost+1<< endl << endl;
                    }
                }
            }
        }

    }

}
*/