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


#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <memory>
#include <string>

#include <algorithm>
#include <bitset>
#include <complex>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <vector>

using namespace std;

#ifdef _MSC_VER
#define __typeof__ decltype
#define strtok_r strtok_s
#endif

#define ITER(c) __typeof__((c).begin())
#define FOREACH(it, c) for (ITER(c) it = (c).begin(); it != (c).end(); ++it)
#define RITER(c) __typeof__((c).rbegin())
#define RFOREACH(it, c) for (RITER(c) it = (c).rbegin(); it != (c).rend(); ++it)
#define REP(i, n) REPEAT(i, 0, n)
#define RREP(i, n) RREPEAT(i, 0, n)
#define REPEAT(i, k, n) for (int i = (k); i < (k + n); ++i)
#define RREPEAT(i, k, n) for (int i = (k) + (n)-1; i >= (k); --i)
#define FROMTO(i, f, t) for (int i = f; i < t; i++)
#define ALL(c) (c).begin(), (c).end()
#define LLPOW(p1, p2) ((ll)pow((double)(p1), (int)p2))
#define ESIZEOF(A) (sizeof(A) / sizeof((A)[0]))
#define CIN_NO_SYNC                                                            \\
  do {                                                                         \\
    cin.tie(0);                                                                \\
    ios_base::sync_with_stdio(false);                                          \\
  } while (0)
#define GETSTR(p) fgets((p), sizeof(p), stdin)
#define CHOMP(p)                                                               \\
  do {                                                                         \\
    char *_q = (p) + strlen(p) - 1;                                            \\
    if (*_q == '\\n' || *_q == '\\r')                                            \\
      *_q = 0;                                                                 \\
  } while (0)
#define FILL(m, v) memset(m, v, sizeof(m))
#define mp make_pair
#define pb push_back
template <class _T> _T MAX(_T p1, _T p2) { return (p1 > p2) ? p1 : p2; }
template <class _T> _T MIN(_T p1, _T p2) { return (p1 < p2) ? p1 : p2; }
template <class _Tv> inline string join(_Tv &v, string sep = " ") {
  ostringstream s;
  FOREACH(it, v) {
    if (it != v.begin())
      s << sep;
    s << *it;
  };
  return s.str();
}

typedef long long ll;
typedef unsigned long long ull;

#define X real()
#define Y imag()
typedef double D;
typedef complex<D> P;
#define EPS (1e-9)

#ifdef _DEBUG
template <class _Tv>
inline void _prfe(const char *_n, _Tv _c, bool _p = false) {
  ITER(_c) _it = _c.begin();
  if (_p) {
    cout << _n << " = [" << endl;
    for (; _it != _c.end(); ++_it)
      cout << "    " << *_it << endl;
    cout << "]" << endl;
  } else {
    cout << _n << " = [ " << *_it++;
    for (; _it != _c.end(); ++_it)
      cout << ", " << *_it;
    cout << " ]" << endl;
  }
}
#define pf printf
#define pr(n)                                                                  \\
  do {                                                                         \\
    cout << #n " = " << (n) << endl;                                           \\
  } while (0)
#define prfe(n) _prfe(#n, n)
#define prfep(n) _prfe(#n, n, true)
#define dbgchk(n)                                                              \\
  do {                                                                         \\
    if (n)                                                                     \\
      throw;                                                                   \\
  } while (0)
#else
#define pf(...)     /* */
#define pr(...)     /* */
#define prfe(...)   /* */
#define prfep(...)  /* */
#define dbgchk(...) /* */
#endif

const int dir[][2] = {{1, 0}, {-1, 0}, {0, 1},  {0, -1},
                      {1, 1}, {-1, 1}, {1, -1}, {-1, -1}};

unsigned int map2int(vector<vector<int>> &v) {
  unsigned int n = 0;
  REP(i, 2) REP(j, 4) n = (n << 3) + v[i][j];
  return n;
}

unsigned int miswap(unsigned int mi, int p1, int p2) {
  unsigned int m1 = (mi >> (p1 * 3)) & 7, m2 = (mi >> (p2 * 3)) & 7;
  unsigned int mi2 = mi;
  mi2 = (mi2 & ~(7 << (p1 * 3))) | m2 << (p1 * 3);
  mi2 = (mi2 & ~(7 << (p2 * 3))) | m1 << (p2 * 3);
  pf("(%08o,%d,%d) %08o\\n", mi, p1, p2, mi2);
  return mi2;
}

unsigned char dp[0x0001000000];

void solve() {
  int x = 0, y = 0;
  unsigned int mi = 01234567;
  deque<pair<unsigned int, pair<int, int>>> q;
  set<unsigned int> s;

  FILL(dp, -1);
  q.pb(mp(mi, mp(x, y)));
  s.insert(mi);
  dp[mi] = 0;

  while (!q.empty()) {
    mi = q.front().first;
    x = q.front().second.first;
    y = q.front().second.second;
    q.pop_front();
    s.erase(mi);
    REP(i, 4) {
      int mx = x + dir[i][0];
      int my = y + dir[i][1];
      if (mx < 0 || mx >= 4 || my < 0 || my >= 2)
        continue;
      unsigned int mi2 = miswap(mi, 7 - (y * 4 + x), 7 - (my * 4 + mx));
      if (dp[mi2] > dp[mi] + 1) {
        dp[mi2] = dp[mi] + 1;
        if (s.find(mi2) == s.end()) {
          pf("enque: %08o, cost = %d\\n", mi2, dp[mi2]);
          s.insert(mi2);
          q.pb(mp(mi2, mp(mx, my)));
        }
      }
    }
  }
}

int main() {
  string s;
  vector<vector<int>> v;
  v.resize(2);
  REP(i, 2) v[i].resize(4);
  solve();

  while (getline(cin, s)) {
    istringstream ss(s);
    REP(i, 4) ss >> v[0][i];
    REP(i, 4) ss >> v[1][i];
    printf("%d\\n", dp[map2int(v)]);
  }
  return 0;
}

Error: TLE

Fixed submission:


#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <memory>
#include <string>

#include <algorithm>
#include <bitset>
#include <complex>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <vector>

using namespace std;

#ifdef _MSC_VER
#define __typeof__ decltype
#define strtok_r strtok_s
#endif

#define ITER(c) __typeof__((c).begin())
#define FOREACH(it, c) for (ITER(c) it = (c).begin(); it != (c).end(); ++it)
#define RITER(c) __typeof__((c).rbegin())
#define RFOREACH(it, c) for (RITER(c) it = (c).rbegin(); it != (c).rend(); ++it)
#define REP(i, n) REPEAT(i, 0, n)
#define RREP(i, n) RREPEAT(i, 0, n)
#define REPEAT(i, k, n) for (int i = (k); i < (k + n); ++i)
#define RREPEAT(i, k, n) for (int i = (k) + (n)-1; i >= (k); --i)
#define FROMTO(i, f, t) for (int i = f; i < t; i++)
#define ALL(c) (c).begin(), (c).end()
#define LLPOW(p1, p2) ((ll)pow((double)(p1), (int)p2))
#define ESIZEOF(A) (sizeof(A) / sizeof((A)[0]))
#define CIN_NO_SYNC                                                            \\
  do {                                                                         \\
    cin.tie(0);                                                                \\
    ios_base::sync_with_stdio(false);                                          \\
  } while (0)
#define GETSTR(p) fgets((p), sizeof(p), stdin)
#define CHOMP(p)                                                               \\
  do {                                                                         \\
    char *_q = (p) + strlen(p) - 1;                                            \\
    if (*_q == '\\n' || *_q == '\\r')                                            \\
      *_q = 0;                                                                 \\
  } while (0)
#define FILL(m, v) memset(m, v, sizeof(m))
#define mp make_pair
#define pb push_back
template <class _T> _T MAX(_T p1, _T p2) { return (p1 > p2) ? p1 : p2; }
template <class _T> _T MIN(_T p1, _T p2) { return (p1 < p2) ? p1 : p2; }
template <class _Tv> inline string join(_Tv &v, string sep = " ") {
  ostringstream s;
  FOREACH(it, v) {
    if (it != v.begin())
      s << sep;
    s << *it;
  };
  return s.str();
}

typedef long long ll;
typedef unsigned long long ull;

#define X real()
#define Y imag()
typedef double D;
typedef complex<D> P;
#define EPS (1e-9)

#ifdef _DEBUG
template <class _Tv>
inline void _prfe(const char *_n, _Tv _c, bool _p = false) {
  ITER(_c) _it = _c.begin();
  if (_p) {
    cout << _n << " = [" << endl;
    for (; _it != _c.end(); ++_it)
      cout << "    " << *_it << endl;
    cout << "]" << endl;
  } else {
    cout << _n << " = [ " << *_it++;
    for (; _it != _c.end(); ++_it)
      cout << ", " << *_it;
    cout << " ]" << endl;
  }
}
#define pf printf
#define pr(n)                                                                  \\
  do {                                                                         \\
    cout << #n " = " << (n) << endl;                                           \\
  } while (0)
#define prfe(n) _prfe(#n, n)
#define prfep(n) _prfe(#n, n, true)
#define dbgchk(n)                                                              \\
  do {                                                                         \\
    if (n)                                                                     \\
      throw;                                                                   \\
  } while (0)
#else
#define pf(...)     /* */
#define pr(...)     /* */
#define prfe(...)   /* */
#define prfep(...)  /* */
#define dbgchk(...) /* */
#endif

const int dir[][2] = {{1, 0}, {-1, 0}, {0, 1},  {0, -1},
                      {1, 1}, {-1, 1}, {1, -1}, {-1, -1}};

unsigned int map2int(vector<vector<int>> &v) {
  unsigned int n = 0;
  REP(i, 2) REP(j, 4) n = (n << 3) + v[i][j];
  return n;
}

unsigned int miswap(unsigned int mi, int p1, int p2) {
  unsigned int m1 = (mi >> (p1 * 3)) & 7, m2 = (mi >> (p2 * 3)) & 7;
  unsigned int mi2 = mi;
  mi2 = (mi2 & ~(7 << (p1 * 3))) | m2 << (p1 * 3);
  mi2 = (mi2 & ~(7 << (p2 * 3))) | m1 << (p2 * 3);
  pf("(%08o,%d,%d) %08o\\n", mi, p1, p2, mi2);
  return mi2;
}

unsigned short dp[0x0001000000];

void solve(vector<vector<int>> &v) {
  int x = 0, y = 0;
  REP(i, 2) REP(j, 4) if (v[i][j] == 0) { x = j, y = i; };
  unsigned int mi = map2int(v);
  deque<pair<unsigned int, pair<int, int>>> q;
  set<unsigned int> s;

  REP(i, 0x1000000) dp[i] = 0xffff;
  q.pb(mp(mi, mp(x, y)));
  s.insert(mi);
  dp[mi] = 0;

  while (!q.empty()) {
    mi = q.front().first;
    x = q.front().second.first;
    y = q.front().second.second;
    q.pop_front();
    s.erase(mi);
    REP(i, 4) {
      int mx = x + dir[i][0];
      int my = y + dir[i][1];
      if (mx < 0 || mx >= 4 || my < 0 || my >= 2)
        continue;
      unsigned int mi2 = miswap(mi, 7 - (y * 4 + x), 7 - (my * 4 + mx));
      if (dp[mi2] > dp[mi] + 1) {
        dp[mi2] = dp[mi] + 1;
        if (s.find(mi2) == s.end()) {
          pf("enque: %08o, cost = %d\\n", mi2, dp[mi2]);
          s.insert(mi2);
          q.pb(mp(mi2, mp(mx, my)));
        }
      }
    }
  }
  cout << dp[01234567] << endl;
}

int main() {
  string s;
  vector<vector<int>> v;
  v.resize(2);
  REP(i, 2) v[i].resize(4);

  while (getline(cin, s)) {
    istringstream ss(s);
    REP(i, 4) ss >> v[0][i];
    REP(i, 4) ss >> v[1][i];
    solve(v);
  }

  return 0;
}