Problem:
Bomb Removal
Problem
縦
H
×横
W
のグリッド上に
N
個の点火された導火線とそれぞれに対する1つの爆弾が配置されている。それぞれの導火線と爆弾は、
L
i
個のマスからなる
path
i
上に配置され、
path
i
の
j
番目のマスを(
px
ij
,
py
ij
)とする。各爆弾は
path
i
の最後のマス(
px
iL
i
,
py
iL
i
)に存在する。導火線の火は初期状態(0秒時点)でマス(
px
i1
,
py
i1
)にあり、1秒間に1マス進む((
px
i1
,
py
i1
),(
px
i2
,
py
i2
),...,(
px
iL
i
,
py
iL
i
)の順に進む)。
最初、ロボットがマス(
sx
,
sy
) にいる。このロボットは今いるマスの隣接する8方向のマスに1進む、または、そのマスに留まるのに1秒かかる。ただし、グリッドの外や爆弾のあるマスには移動することができない。ロボットは導火線の火があるマス上にいるとき消火することができる(同じマスに2つ以上の導火線の火がある場合はそれら全てを消すことができる)。
爆弾は導火線の火がマス(
px
iL
i
,
py
iL
i
)に到達したときに爆発する(
path
i
の途中で導火線の火がマス(
px
iL
i
,
py
iL
i
)を通過したときは爆弾は爆発しない)。
全ての爆弾を爆発させずに全ての導火線の火を消火させるための最短の時間を出力せよ。ただし、どのように移動しても爆弾を爆発させてしまう場合は-1を出力せよ。なお、初期状態(0秒時点)でロボットが導火線の火の上にいる場合、消火することができる。
Input
入力は以下の形式で与えられる。
W
H
N
sx
sy
L
1
path
1
L
2
path
2
...
L
N
path
N
1行目に3つの整数
W
,
H
,
N
が空白区切りで与えられる。2行目に2つの整数
sx
,
sy
が空白区切りで与えられる。3行目から
N
+2行目に
L
i
と
path
i
が与えられる。
path
i
は以下の形式で与えられる。
px
i1
py
i1
px
i2
py
i2
...
px
iL
i
py
iL
i
Constraints
2 ≤
H
,
W
≤ 20
1 ≤
N
≤ 5
1 ≤
sx
≤
W
1 ≤
sy
≤
H
2 ≤
L
i
≤
H
+
W
1 ≤
px
ij
≤
W
1 ≤
py
ij
≤
H
path
i
の隣り合うマスは上下左右に隣接している。
導火線は互いに独立している(他の導火線に影響しない)。
爆弾はマス(
sx
,
sy
)には置かれない。
Output
ロボットが全ての導火線の火を消火させるための最短時間または -1 を出力せよ。
Sample Input 1
2 2 1
2 1
3 1 1 1 2 2 2
Sample Output 1
1
サンプル1に対応する図は以下の通りである。
ロボットは1秒後に左下の(1, 2)のマスに移動することにより消火することができる。
Sample Input 2
2 2 1
2 1
2 1 1 1 2
Sample Output 2
-1
サンプル2に対応する図は以下の通りである。
ロボットは、(1, 1)または(2, 2)のマスに移動する、または今いるマス(2, 1)に留まることができるがいずれにせよ1秒後に爆弾が爆発してしまう。
Sample Input 3
3 3 2
1 3
3 2 3 2 2 2 1
5 2 1 1 1 1 2 2 2 3 2
Sample Output 3
2
サンプル3に対応する図は以下の通りである。
ロボットは、(2, 2)のマスに移動し、(1, 2)のマスに移動することにより2秒で全ての導火線の火を消火することができる。
Sample Input 4
3 3 1
2 2
2 2 2 2 1
Sample Output 4
0
ロボットは、初期状態(0秒時点)で(2, 2)のマスにいて、導火線の火も(2, 2)のマスにあるので0秒で消火することができる。

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;
using LL = long long;
using VL = vector<LL>;
using VVL = vector<VL>;
using PLL = pair<LL, LL>;
using VS = vector<string>;

#define ALL(a)  begin((a)),end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))
#define UNIQ(c) (c).erase(unique(ALL((c))), end((c)))

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)

#define FF first
#define SS second

#define DUMP(x) cout<<#x<<":"<<(x)<<endl
template<class S, class T>
istream& operator>>(istream& is, pair<S,T>& p){
  return is >> p.FF >> p.SS;
}
template<class T>
istream& operator>>(istream& is, vector<T>& xs){
  for(auto& x: xs)
	is >> x;
  return is;
}
template<class S, class T>
ostream& operator<<(ostream& os, const pair<S,T>& p){
  return os << p.FF << " " << p.SS;
}
template<class T>
ostream& operator<<(ostream& os, const vector<T>& xs){
  for(unsigned int i=0;i<xs.size();++i)
	os << (i?" ":"") << xs[i];
  return os;
}
template<class T>
void maxi(T& x, T y){
  if(x < y) x = y;
}
template<class T>
void mini(T& x, T y){
  if(x > y) x = y;
}


const double EPS = 1e-10;
const double PI  = acos(-1.0);
const LL MOD = 1e9+7;
const int INF = 1e9;

int dp[1<<5][41][21][21];
int dir[] = {-1,0,1};

int main(){
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  int W, H, N;
  cin >> W >> H >> N;
  int BB = (1<<N) - 1;
  PII s;
  cin >> s;
  --s.FF;
  --s.SS;
  vector<vector<PII>> bm(N);
  int init = 0;
  REP(i,N){
	int L;
	cin >> L;
	REP(j,L){
	  PII p;
	  cin >> p;
	  --p.FF;
	  --p.SS;
	  bm[i].EB(p);
	}
	if(bm[i][0] == s) init |= 1<<i;
  }

  auto isin = [W,H](const PII& p){ return 0 <= p.FF && p.FF < W && 0 <= p.SS && p.SS < H; };
  using D = pair<PII,PII>;
  fill((int*)dp, (int*)dp+(1<<5)*41*21*21, INF);
  queue<D> q;
  q.push(MP(MP(init,0),s));
  dp[init][0][s.FF][s.SS] = 0;
  int ans = -1;
  while(!q.empty()){
	auto dd = q.front();
	q.pop();
	if(dd.FF.FF == BB){
	  ans = dd.FF.SS;
	  break;
	}

	int ntime = dd.FF.SS+1;
	REP(dx,3) REP(dy,3){
	  PII np(dd.SS.FF+dir[dx], dd.SS.SS+dir[dy]);
	  if(!isin(np)) continue;
	  bool ok = true;
	  REP(i,N) if(bm[i].back() == np){ ok = false; break;}
	  if(!ok) continue;

	  bool bomb = false;
	  PII ns(dd.FF.FF, ntime);
	  REP(i,N){
		if(ns.FF>>i&1) continue;
		if(ntime >= SZ(bm[i])-1){
		  bomb = true;
		  break;
		}
		else if(bm[i][ntime] == np)
		  ns.FF |= 1<<i;
	  }
	  if(bomb) continue;

	  if(dp[ns.FF][ns.SS][np.FF][np.SS] == INF){
		dp[ns.FF][ns.SS][np.FF][np.SS] = ntime;
		q.push(MP(ns,np));
	  }
	}
  }
  
  cout << ans << endl;

  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 5872
final_rank: 10

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i,n) REP(i,0,n)
#define REP(i,s,e) for(int i=(s); i<(int)(e); i++)
#define repr(i, n) REPR(i, n, 0)
#define REPR(i, s, e) for(int i=(int)(s-1); i>=(int)(e); i--)
#define pb push_back
#define all(r) r.begin(),r.end()
#define rall(r) r.rbegin(),r.rend()
#define fi first
#define se second

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int INF = 1e9;
const ll MOD = 1e9 + 7;
double EPS = 1e-8;

// #define DEBUG_MODE
#ifdef DEBUG_MODE
#define dump(x) cout << #x << " : " << x << endl
#define LINE cout << "line : " << __LINE__ << endl
#define dumpV(v) cout << #v << " : ["; for(auto& t : v) cout << t << ", "; cout<<"]" << endl
#define STOP assert(false)
#else
#define dump(x) ;
#define LINE     ;
#define dumpV(v);
#define STOP     ;
#endif
#define mp make_pair

namespace std{
  template<class S,class T>
  ostream &operator <<(ostream& out,const pair<S,T>& a){
    out<<'('<<a.fi<<", "<<a.se<<')';
    return out;
  }
}



const int MAX_N = 5;
const int MAX_H = 20;
const int MAX_W = 20;
const int MAX_HW = MAX_H * MAX_W;


// vertex => y, x, mask | 20 * 20 * 2^5
// edge => (x, y, t)^2 | (400*40)^2

int dist[MAX_HW][1 << MAX_N];

int times[MAX_HW][MAX_HW];

bool isBomb[MAX_HW];

auto isOutOfRange = [](int h, int w, int H, int W) {
    return h < 0 || h >= H || w < 0 || w >= W;
};


int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int W, H, N;
    cin >> W >> H >> N;
    int sx, sy;
    cin >> sx >> sy;
    --sx; --sy;
    vector<vector<int>> paths(N);
    rep(i, N) {
        int sz;
        cin >> sz;
        paths[i].resize(sz-1);
        rep(j, sz) {
            int x, y;
            cin >> x >> y;
            --x; --y;
            if (j + 1 == sz) isBomb[y * W + x] = true;
            else paths[i][j] = (y * W + x);
        }
    }
    int HW = H * W;
    {
        rep(i, HW) rep(j, HW) times[i][j] = (i == j ? 0 : INF);
        rep(y, H) rep(x, W) if (!isBomb[y * W + x]) {
            REP(dy, -1, 2) REP(dx, -1, 2)  if(dx|dy) {
                int nx = x + dx, ny = y + dy;
                if (isOutOfRange(ny, nx, H, W) || isBomb[ny * W + nx]) continue;
                times[y * W + x][ny * W + nx] = 1;
            }
        }
        rep(k, HW) rep(i, HW) rep(j, HW) times[i][j] = min(times[i][j], times[i][k] + times[k][j]);
    }
    rep(i, MAX_HW) rep(j, 1 << MAX_N) dist[i][j] = INF;
    using P = pair<int, pii>;
    priority_queue<P, vector<P>, greater<P> > q;
    {
        int mask = 0;
        int S = sy * W + sx;
        rep(i, N) {
            if (S == paths[i][0]) mask |= (1 << i);
        }
        dist[S][mask] = 0;
        q.push({0, {S, mask}});
    }

    {
        while (!q.empty()) {
            auto p = q.top(); q.pop();
            auto yx = p.se.fi, mask = p.se.se, t = p.fi;
            if (dist[yx][mask] < t) continue;
            dump(p);
            rep(i, N) if ((mask & (1 << i)) == 0) {
                int nmask = mask | (1<<i);
                REP(j, t, paths[i].size()) {
                    auto nyx = paths[i][j];
                    int dt = j - t;
                    dump(mp(i, j));
                    dump(times[yx][nyx]);
                    if(times[yx][nyx] <= dt && j < dist[nyx][nmask]) {
                        dist[nyx][nmask] = j;
                        q.push({j, {nyx, nmask}});
                    }
                }
            }
        }
    };
    int ans = INF;
    rep(i, HW) ans = min(ans, dist[i][(1<<N)-1]);
    cout << (ans == INF ? -1 : ans) << '\n';
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3892
final_rank: 12

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i,n) REP(i,0,n)
#define REP(i,s,e) for(int i=(s); i<(int)(e); i++)
#define repr(i, n) REPR(i, n, 0)
#define REPR(i, s, e) for(int i=(int)(s-1); i>=(int)(e); i--)
#define pb push_back
#define all(r) r.begin(),r.end()
#define rall(r) r.rbegin(),r.rend()
#define fi first
#define se second

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int INF = 1e9;
const ll MOD = 1e9 + 7;
double EPS = 1e-8;

// #define DEBUG_MODE
#ifdef DEBUG_MODE
#define dump(x) cout << #x << " : " << x << endl
#define LINE cout << "line : " << __LINE__ << endl
#define dumpV(v) cout << #v << " : ["; for(auto& t : v) cout << t << ", "; cout<<"]" << endl
#define STOP assert(false)
#else
#define dump(x) ;
#define LINE     ;
#define dumpV(v);
#define STOP     ;
#endif
#define mp make_pair

namespace std{
  template<class S,class T>
  ostream &operator <<(ostream& out,const pair<S,T>& a){
    out<<'('<<a.fi<<", "<<a.se<<')';
    return out;
  }
}



const int MAX_N = 5;
const int MAX_H = 20;
const int MAX_W = 20;
const int MAX_HW = MAX_H * MAX_W;


// vertex => y, x, mask | 20 * 20 * 2^5
// edge => (x, y, t)^2 | (400*40)^2

int dist[MAX_HW][1 << MAX_N];

int times[MAX_HW][MAX_HW];

bool isBomb[MAX_HW];

auto isOutOfRange = [](int h, int w, int H, int W) {
    return h < 0 || h >= H || w < 0 || w >= W;
};


int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int W, H, N;
    cin >> W >> H >> N;
    int sx, sy;
    cin >> sx >> sy;
    --sx; --sy;
    vector<vector<int>> paths(N);
    rep(i, N) {
        int sz;
        cin >> sz;
        paths[i].resize(sz-1);
        rep(j, sz) {
            int x, y;
            cin >> x >> y;
            --x; --y;
            if (j + 1 == sz) isBomb[y * W + x] = true;
            else paths[i][j] = (y * W + x);
        }
    }
    int HW = H * W;
    {
        rep(i, HW) rep(j, HW) times[i][j] = (i == j ? 0 : INF);
        rep(y, H) rep(x, W) if (!isBomb[y * W + x]) {
            REP(dy, -1, 2) REP(dx, -1, 2)  if(dx|dy) {
                int nx = x + dx, ny = y + dy;
                if (isOutOfRange(ny, nx, H, W) || isBomb[ny * W + nx]) continue;
                times[y * W + x][ny * W + nx] = 1;
            }
        }
        rep(k, HW) rep(i, HW) rep(j, HW) times[i][j] = min(times[i][j], times[i][k] + times[k][j]);
    }
    rep(i, MAX_HW) rep(j, 1 << MAX_N) dist[i][j] = INF;
    using P = pair<int, pii>;
    priority_queue<P, vector<P>, greater<P> > q;
    {
        int mask = 0;
        int S = sy * W + sx;
        rep(i, N) {
            if (S == paths[i][0]) mask |= (1 << i);
        }
        dist[S][mask] = 0;
        q.push({0, {S, mask}});
    }

    {
        while (!q.empty()) {
            auto p = q.top(); q.pop();
            auto yx = p.se.fi, mask = p.se.se, t = p.fi;
            if (dist[yx][mask] < t) continue;
            dump(p);
            rep(i, N) if ((mask & (1 << i)) == 0) {
                int nmask = mask | (1<<i);
                REP(j, t + 1, paths[i].size()) {
                    auto nyx = paths[i][j];
                    int dt = j - t;
                    dump(mp(i, j));
                    dump(times[yx][nyx]);
                    if(times[yx][nyx] <= dt && j < dist[nyx][nmask]) {
                        dist[nyx][nmask] = j;
                        q.push({j, {nyx, nmask}});
                    }
                }
            }
        }
    };
    int ans = INF;
    rep(i, HW) ans = min(ans, dist[i][(1<<N)-1]);
    cout << (ans == INF ? -1 : ans) << '\n';
    return 0;
}
accuracy: 0.45
time_ms: 40
memory_kb: 3792
final_rank: 17

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i,n) REP(i,0,n)
#define REP(i,s,e) for(int i=(s); i<(int)(e); i++)
#define repr(i, n) REPR(i, n, 0)
#define REPR(i, s, e) for(int i=(int)(s-1); i>=(int)(e); i--)
#define pb push_back
#define all(r) r.begin(),r.end()
#define rall(r) r.rbegin(),r.rend()
#define fi first
#define se second

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int INF = 1e9;
const ll MOD = 1e9 + 7;
double EPS = 1e-8;

// #define DEBUG_MODE
#ifdef DEBUG_MODE
#define dump(x) cout << #x << " : " << x << endl
#define LINE cout << "line : " << __LINE__ << endl
#define dumpV(v) cout << #v << " : ["; for(auto& t : v) cout << t << ", "; cout<<"]" << endl
#define STOP assert(false)
#else
#define dump(x) ;
#define LINE     ;
#define dumpV(v);
#define STOP     ;
#endif
#define mp make_pair

namespace std{
  template<class S,class T>
  ostream &operator <<(ostream& out,const pair<S,T>& a){
    out<<'('<<a.fi<<", "<<a.se<<')';
    return out;
  }
}



const int MAX_N = 5;
const int MAX_H = 20;
const int MAX_W = 20;
const int MAX_HW = MAX_H * MAX_W;


// vertex => y, x, mask | 20 * 20 * 2^5
// edge => (x, y, t)^2 | (400*40)^2

int dist[MAX_HW][1 << MAX_N];

int times[MAX_HW][MAX_HW];

bool isBomb[MAX_HW];

auto isOutOfRange = [](int h, int w, int H, int W) {
    return h < 0 || h >= H || w < 0 || w >= W;
};


int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int W, H, N;
    cin >> W >> H >> N;
    int sx, sy;
    cin >> sx >> sy;
    --sx; --sy;
    vector<vector<int>> paths(N);
    rep(i, N) {
        int sz;
        cin >> sz;
        paths[i].resize(sz-1);
        rep(j, sz) {
            int x, y;
            cin >> x >> y;
            --x; --y;
            if (j + 1 == sz) isBomb[y * W + x] = true;
            else paths[i][j] = (y * W + x);
        }
    }
    int HW = H * W;
    {
        rep(i, HW) rep(j, HW) times[i][j] = (i == j ? 0 : INF);
        rep(y, H) rep(x, W) if (!isBomb[y * W + x]) {
            REP(dy, -1, 2) REP(dx, -1, 2)  {
                int nx = x + dx, ny = y + dy;
                if (isOutOfRange(ny, nx, H, W) || isBomb[ny * W + nx]) continue;
                times[y * W + x][ny * W + nx] = 1;
            }
        }
        rep(k, HW) rep(i, HW) rep(j, HW) times[i][j] = min(times[i][j], times[i][k] + times[k][j]);
    }
    rep(i, MAX_HW) rep(j, 1 << MAX_N) dist[i][j] = INF;
    using P = pair<int, pii>;
    priority_queue<P, vector<P>, greater<P> > q;
    {
        int mask = 0;
        int S = sy * W + sx;
        rep(i, N) {
            if (S == paths[i][0]) mask |= (1 << i);
        }
        dist[S][mask] = 0;
        q.push({0, {S, mask}});
    }

    {
        while (!q.empty()) {
            auto p = q.top(); q.pop();
            auto yx = p.se.fi, mask = p.se.se, t = p.fi;
            if (dist[yx][mask] < t) continue;
            dump(p);
            rep(i, N) if ((mask & (1 << i)) == 0) {
                int nmask = mask | (1<<i);
                REP(j, t + 1, paths[i].size()) {
                    auto nyx = paths[i][j];
                    int dt = j - t;
                    dump(mp(i, j));
                    dump(times[yx][nyx]);
                    if(times[yx][nyx] <= dt && j < dist[nyx][nmask]) {
                        dist[nyx][nmask] = j;
                        q.push({j, {nyx, nmask}});
                    }
                }
            }
        }
    };
    int ans = INF;
    rep(i, HW) ans = min(ans, dist[i][(1<<N)-1]);
    cout << (ans == INF ? -1 : ans) << '\n';
    return 0;
}
accuracy: 0.45
time_ms: 50
memory_kb: 3844
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

using pi = pair<int,int>;

const int dx[9]={1,1,1,0,0,0,-1,-1,-1};
const int dy[9]={1,0,-1,1,0,-1,1,0,-1};

const int T = 44;
bool vis[20][20][T][1<<5]={};

struct State{
    int y,x,t,mask;
};

int solve(){
    int w,h,n;
    cin >>w >>h >>n;

    pi s;
    cin >>s.se >>s.fi;
    --s.fi;
    --s.se;

    set<pi> bomb;
    vector<vector<pi>> l(n);
    rep(i,n){
        int L;
        cin >>L;
        rep(j,L){
            int x,y;
            cin >>x >>y;
            --x;
            --y;
            l[i].pb({y,x});
        }
        bomb.insert(l[i][L-1]);
    }

    auto IN = [&](int y, int x){
        return 0<=y && y<h && 0<=x && x<w;
    };

    queue<State> que;
    vis[s.fi][s.se][0][0] = true;
    que.push({s.fi,s.se,0,0});
    while(!que.empty()){
        State c = que.front();
        que.pop();
        if(c.t==T-1) break;

        int nmask = c.mask;
        rep(i,n){
            int L = l[i].size();
            if(c.t<L && l[i][c.t] == pi(c.y,c.x)) nmask |= (1<<i);
        }
        if(!vis[c.y][c.x][c.t][nmask]){
            vis[c.y][c.x][c.t][nmask] = true;
            que.push({c.y,c.x,c.t,nmask});
        }

        rep(d,9){
            int ny = c.y+dy[d], nx = c.x+dx[d];
            if(IN(ny,nx) && !bomb.count({ny,nx}) && !vis[ny][nx][c.t+1][c.mask]){
                vis[ny][nx][c.t+1][c.mask] = true;
                que.push({ny,nx,c.t+1,c.mask});
            }
        }
    }

    rep(i,T){
        rep(y,h)rep(x,w){
            if(vis[y][x][i][(1<<n)-1]) return i;
        }
    }
    return -1;
}

int main(){
    cout << solve() << endl;
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3836
final_rank: 4

code_snippet: #include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

int w,h,n;
int l[5];
P path[5][50];
bool dp[405][25][25][1<<6];
int fie[25][25];

int solve(int sx,int sy){
	memset(dp,false,sizeof(dp));
	
	int rect=0;
	for(int a=0;a<n;a++){
		P p=path[a][0];
		if(p.first==sy && p.second==sx)rect+=(1<<a);
	}
	dp[0][sy][sx][rect]=true;
	for(int i=0;i<=w+h+1;i++){
		for(int bit=0;bit<(1<<n);bit++){
			for(int j=0;j<h;j++){
				for(int k=0;k<w;k++){
					if(!dp[i][j][k][bit])continue;
					//printf("%d %d %d %d\n",i,j,k,bit);
					if((bit+1)==(1<<n))return i;
					for(int a=-1;a<=1;a++){
						for(int b=-1;b<=1;b++){
							int nj=j+a;
							int nk=k+b;
							if(nj<0 || nj>=h || nk<0 || nk>=w)continue;
							if(fie[nj][nk]==-1)continue;
							int rec=0;
							for(int g=0;g<n;g++){
								if(bit>>g & 1)continue;
								P p=path[g][i+1];
								if(p.first==nj && p.second==nk)rec+=(1<<g);
							}
							dp[i+1][nj][nk][bit+rec]=true;
						}
					}
				}
			}
		}
	}
	return -1;
}

int main(void){
	scanf("%d%d%d",&w,&h,&n);
	int sx,sy;
	scanf("%d%d",&sx,&sy);
	sx--;
	sy--;
	for(int i=0;i<n;i++){
		scanf("%d",&l[i]);
		for(int j=0;j<l[i];j++){
			P p;
			scanf("%d%d",&p.second,&p.first);
			p.second--;
			p.first--;
			path[i][j]=p;
			if((j+1)==l[i]){
				fie[p.first][p.second]=-1;
				path[i][j]=P(-1,-1);
			}
		}
		for(int j=l[i];j<50;j++){
			path[i][j]=P(-1,-1);
		}
	}
	printf("%d\n",solve(sx,sy));
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 19048
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcount

#define INF 1e16
#define mod 1000000007

ll W,H,N;
ll sx,sy;
vector<P> ps[5];
map<P,bool> dame;

bool vis[20][20][50][1<<5];
ll di[]={-1,-1,-1,0,0,1,1,1,0};
ll dj[]={-1,0,1,-1,1,-1,0,1,0};

struct state{
  ll i,j,t,S;
};

int main(){
  cin>>W>>H>>N;
  cin>>sx>>sy;
  sx--;sy--;
  rep(i,N){
    int tmp;
    cin>>tmp;
    rep(j,tmp){
      int a,b;
      cin>>b>>a;
      a--;b--;
      ps[i].push_back(P(a,b));
    }
    dame[ps[i][tmp-1]]=true;
  }

  queue<state> que;
  vis[sy][sx][0][0]=true;
  que.push((state){sy,sx,0,0});
  while(que.size()){
    state crt=que.front(); que.pop();

    ll nS=crt.S;
    rep(i,N){
      if(crt.t<(ll)ps[i].size()&&ps[i][crt.t]==P(crt.i,crt.j))nS|=(1<<i);
    }
    if(!vis[crt.i][crt.j][crt.t][nS]){
      vis[crt.i][crt.j][crt.t][nS]=true;
      que.push((state){crt.i,crt.j,crt.t,nS});
    }

    rep(dir,9){
      ll ni=crt.i+di[dir],nj=crt.j+dj[dir];
      if(ni>=0&&ni<H&&nj>=0&&nj<W&&crt.t+1<50&&!dame[P(ni,nj)]&&!vis[ni][nj][crt.t+1][crt.S]){
        vis[ni][nj][crt.t+1][crt.S]=true;
        que.push((state){ni,nj,crt.t+1,crt.S});
      }
    }
  }

  rep(t,50){
    rep(i,H)rep(j,W){
      if(vis[i][j][t][(1<<N)-1]){
        cout<<t<<endl;
        return 0;
      }
    }
  }
  cout<<-1<<endl;

  return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 4088
final_rank: 15

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
const ld eps = 1e-9;


int W, H, N;
vector<vector<int>> get_dis(int nx, int ny, const vector<pair<int,int>>&bombs) {
	int dx[] = { -1,-1,0,1,1,1,0,-1 };
	int dy[] = { 0,1,1,1,0,-1,-1,-1 };


	vector<vector<int>>times(H,vector<int>(W,1e9));

	times[ny][nx]=0;

	queue<pair<int,int>>que;
	que.emplace(nx,ny);
	while (!que.empty()) {
		auto atop(que.front());
		que.pop();

		int now_x=atop.first;
		int now_y=atop.second;
		int now_time=times[now_y][now_x];
		for (int way = 0; way < 8; ++way) {
			int next_x=now_x+dx[way];
			int next_y=now_y+dy[way];

			if(next_x<0||next_x>=W||next_y<0||next_y>=H)continue;
			if(find(bombs.begin(),bombs.end(),make_pair(next_x,next_y))!=bombs.end())continue;

			if (times[next_y][next_x] > now_time + 1) {
				times[next_y][next_x]=now_time+1;
				que.push(make_pair(next_x,next_y));
			}
		}
	}

	return times;
}

int get_atime(int nx, int ny, const vector<pair<int, int>>&path, const int ntime,const vector<pair<int,int>>bombs) {

	auto times=get_dis(nx,ny,bombs);

	for (int i = ntime; i < path.size(); ++i) {
		int px=path[i].first;
		int py=path[i].second;

		int dis=times[py][px];

		if(dis<=i-ntime)return i;
	}
	return -1;
}


int main() {cin>>W>>H>>N;

	int sx,sy;cin>>sx>>sy;
	sx--;sy--;

	vector<vector<pair<int,int>>>paths(N);

	vector<pair<int,int>>bombs(N);
	for (int i = 0; i < N; ++i) {
		int p;cin>>p;
		for (int j = 0; j < p; ++j) {
			int x,y;cin>>x>>y;x--;y--;

			if (j == p - 1) {
				bombs.emplace_back(x,y);
			}
			else {

				paths[i].emplace_back(x, y);

			}
		}
	}

	vector<int>perms(N);

	iota(perms.begin(),perms.end(),0);


	int ans=1e8;
	do {

		int now_x=sx;
		int now_y=sy;
		int now_time=0;
		for (int i = 0; i < N; ++i) {
			const int next_bomb_id=perms[i];

			int next_time=get_atime(now_x,now_y,paths[next_bomb_id],now_time,bombs);
			if (next_time == -1) {
				now_time=1e8;
				break;
			}
			else {
				now_time=next_time;
				now_x=paths[next_bomb_id][next_time].first;
				now_y=paths[next_bomb_id][next_time].second;
			}
		}
		ans=min(ans,now_time);
	}while(next_permutation(perms.begin(),perms.end()));

	if(ans>1e7)ans=-1;
	cout<<ans<<endl;
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3172
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;

using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;
using LL = long long;
using VL = vector<LL>;
using VVL = vector<VL>;
using PLL = pair<LL, LL>;
using VS = vector<string>;

#define ALL(a)  begin((a)),end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))
#define UNIQ(c) (c).erase(unique(ALL((c))), end((c)))

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)

#define FF first
#define SS second

#define DUMP(x) cout<<#x<<":"<<(x)<<endl
template<class S, class T>
istream& operator>>(istream& is, pair<S,T>& p){
  return is >> p.FF >> p.SS;
}
template<class T>
istream& operator>>(istream& is, vector<T>& xs){
  for(auto& x: xs)
	is >> x;
  return is;
}
template<class S, class T>
ostream& operator<<(ostream& os, const pair<S,T>& p){
  return os << p.FF << " " << p.SS;
}
template<class T>
ostream& operator<<(ostream& os, const vector<T>& xs){
  for(unsigned int i=0;i<xs.size();++i)
	os << (i?" ":"") << xs[i];
  return os;
}
template<class T>
void maxi(T& x, T y){
  if(x < y) x = y;
}
template<class T>
void mini(T& x, T y){
  if(x > y) x = y;
}


const double EPS = 1e-10;
const double PI  = acos(-1.0);
const LL MOD = 1e9+7;
const int INF = 1e9;

int dp[1<<5][41][21][21];
int dir[] = {-1,0,1};

int main(){
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  int W, H, N;
  cin >> W >> H >> N;
  int BB = (1<<N) - 1;
  PII s;
  cin >> s;
  --s.FF;
  --s.SS;
  vector<vector<PII>> bm(N);
  int init = 0;
  REP(i,N){
	int L;
	cin >> L;
	REP(j,L){
	  PII p;
	  cin >> p;
	  --p.FF;
	  --p.SS;
	  bm[i].EB(p);
	}
	if(bm[i][0] == s) init |= 1<<i;
  }

  auto isin = [W,H](const PII& p){ return 0 <= p.FF && p.FF < W && 0 <= p.SS && p.SS < H; };
  using D = pair<PII,PII>;
  fill((int*)dp, (int*)dp+(1<<5)*41*21*21, INF);
  queue<D> q;
  q.push(MP(MP(init,0),s));
  dp[init][0][s.FF][s.SS] = 0;
  int ans = -1;
  while(!q.empty()){
	auto dd = q.front();
	q.pop();
	if(dd.FF.FF == BB){
	  ans = dd.FF.SS;
	  break;
	}

	int ntime = dd.FF.SS+1;
	REP(dx,3) REP(dy,3){
	  PII np(dd.SS.FF+dir[dx], dd.SS.SS+dir[dy]);
	  if(!isin(np)) continue;
	  bool ok = true;
	  REP(i,N) if(bm[i].back() == np){ ok = false; break;}
	  if(!ok) continue;

	  bool bomb = false;
	  PII ns(dd.FF.FF, ntime);
	  REP(i,N){
		if(ns.FF>>i&1) continue;
		if(ntime >= SZ(bm[i])-1){
		  bomb = true;
		  break;
		}
		else if(bm[i][ntime] == np)
		  ns.FF |= 1<<i;
	  }
	  if(bomb) continue;

	  if(dp[ns.FF][ns.SS][np.FF][np.SS] == INF){
		dp[ns.FF][ns.SS][np.FF][np.SS] = ntime;
		q.push(MP(ns,np));
	  }
	}
  }
  
  cout << ans << endl;

  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 5496
final_rank: 7

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Data{
	Data(){
		row = col = 0;
	}
	Data(int arg_row,int arg_col){
		row = arg_row;
		col = arg_col;
	}
	int row,col;
};

struct Info{
	Info(int arg_state,int arg_row,int arg_col,int arg_time){
		state = arg_state;
		row = arg_row;
		col = arg_col;
		time = arg_time;
	}
	int state,row,col,time;
};

int W,H,N;
int num_path[5];
bool state_check[20][20][32][41];
int diff_row[9] = {-1,-1,-1,0,0,0,1,1,1},diff_col[9] = {-1,0,1,-1,0,1,-1,0,1};
bool bomb_check[20][20];
Data path[5][40];

bool rangeCheck(int row,int col){
	if(row >= 0 && row <= H-1 && col >= 0 && col <= W-1){
		return true;
	}else{
		return false;
	}
}

int main(){

	int POW[6];
	for(int i = 0; i < 6; i++)POW[i] = pow(2,i);


	scanf("%d %d %d",&W,&H,&N);

	int start_col,start_row;
	scanf("%d %d",&start_col,&start_row);
	start_col--;
	start_row--;

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++)bomb_check[row][col] = false;
	}

	for(int i = 0; i < N; i++){
		scanf("%d",&num_path[i]);

		for(int k = 0; k < num_path[i]; k++){
			scanf("%d %d",&path[i][k].col,&path[i][k].row);
			path[i][k].col--;
			path[i][k].row--;
			if(k == num_path[i]-1){
				bomb_check[path[i][k].row][path[i][k].col] = true;
			}
		}
	}

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			for(int state = 0; state < POW[N]; state++){
				for(int time = 0; time <= 40; time++)state_check[row][col][state][time] = false;
			}
		}
	}

	int first_state = 0;
	for(int i = 0; i < N; i++){
		if(path[i][0].row == start_row && path[i][0].col == start_col){
			first_state += POW[i];
		}
	}

	state_check[start_row][start_col][first_state][0] = true;

	queue<Info> Q;
	Q.push(Info(first_state,start_row,start_col,0));

	int ans = -1;
	int adj_row,adj_col,next_time,add_state;
	bool FLG;

	while(!Q.empty()){

		if(Q.front().state == POW[N]-1){
			ans = Q.front().time;
			break;
		}else{

			next_time = Q.front().time+1;

			FLG = true;
			for(int loop = 0; loop < N; loop++){
				if(Q.front().state & (1 << loop)){
					//Do nothing
				}else{
					if(next_time == num_path[loop]-1){
						FLG = false;
						break;
					}
				}
			}

			if(!FLG){
				Q.pop();
				continue;
			}

			for(int i = 0; i < 9; i++){
				adj_row = Q.front().row+diff_row[i];
				adj_col = Q.front().col+diff_col[i];

				if(rangeCheck(adj_row,adj_col) == false || bomb_check[adj_row][adj_col] == true)continue;

				add_state = 0;

				for(int loop = 0; loop < N; loop++){
					if(Q.front().state & (1 << loop)){
						//Do nothing
					}else{
						if(path[loop][next_time].row == adj_row && path[loop][next_time].col == adj_col){
							add_state += POW[loop];
						}
					}
				}
				if(state_check[adj_row][adj_col][Q.front().state+add_state][next_time])continue;

				state_check[adj_row][adj_col][Q.front().state+add_state][next_time] = true;

				Q.push(Info(Q.front().state+add_state,adj_row,adj_col,next_time));
			}
			Q.pop();
		}
	}

	printf("%d\n",ans);

    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 4076
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
#include <queue>
#include <tuple>

using pii   = std::pair<int, int>;
using State = std::tuple<int, int, int, int>;

constexpr int MAXT = 40;
constexpr int INF  = (1 << 29);

int main()
{
    int W, H, N, sx, sy;
    std::cin >> W >> H >> N >> sx >> sy;
    sx--; sy--;
    
    std::vector<std::vector<pii>> paths(N);
    std::vector<std::vector<bool>> pass(H, std::vector<bool>(W, true));
    
    int closed = 0;
    for (int i = 0; i < N; i++) {
        int L;
        std::cin >> L;
        
        std::vector<pii> path(L);        
        for (int j = 0; j < L; j++) {
            int x, y;
            std::cin >> x >> y;
            x--; y--;
            path[j] = {x, y};
            
            if (j == 0 && x == sx && y == sy) {
                closed |= 1 << i;
            }

            if (j == L - 1) {
                pass[y][x] = false;
            }
        }

        paths[i] = path;
    }
    
    
    int d[H][W][1 << N][MAXT];
    std::fill(d[0][0][0], d[0][0][0] + H * W * (1 << N) * MAXT, INF);
    
    d[sy][sx][closed][0] = 0;
    
    std::queue<State> Q;
    Q.push(State(sx, sy, closed, 0));

    constexpr int dx[] = {-1, -1, -1, +0, +0, +0, +1, +1, +1};
    constexpr int dy[] = {-1, +0, +1, -1, +0, +1, -1, +0, +1};
    
    int ret = -1;
    while (!Q.empty()) {
        int x, y, S, t;
        std::tie(x, y, S, t) = Q.front(); Q.pop();

        auto is_timeup = [&]() -> bool {
            for (int i = 0; i < N; i++) {
                if (!(S >> i & 1) && (int)paths[i].size() <= t) {
                    return true;
                }               
            }
            return false;
        };
        
        if (is_timeup()) {
            continue;
        }
        
        if (S == (1 << N) - 1) {
            ret = t;
            break;
        }

        for (int i = 0; i < 9; i++) {
            int nx = x + dx[i], ny = y + dy[i]; // robot's next position
            if (nx < 0 || nx >= W || ny < 0 || ny >= H || !pass[ny][nx]) {
                continue;
            }
            
            int nS = S;
            for (int j = 0; j < N; j++) {
                if ((int)paths[j].size() <= t + 1) { continue; }
                
                int fx, fy; // fire's next position
                std::tie(fx, fy) = paths[j][t + 1];
                
                if (fx == nx && fy == ny) {
                    nS |= 1 << j;
                }
            }

            if (t + 1 < d[ny][nx][nS][t + 1]) {
                d[ny][nx][nS][t + 1] = t + 1;
                Q.push(State(nx, ny, nS, t + 1));
            }
        }
    }

    std::cout << ret << std::endl;
    
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 5252
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
struct PP {int k,t,x,y;};
int dx[9]={-1,-1,-1,0,0,0,1,1,1},dy[9]={-1,0,1,-1,0,1,-1,0,1};
bool check(int n,int m,int x,int y) {return x>=0&&x<n&&y>=0&&y<m;}
int main() {
  int h,w,n,sx,sy,ans=-1,t=0;
  cin >> h >> w >> n >> sx >> sy;
  sx--,sy--;
  vector<P> v[n];
  queue<PP> que;
  bool d[41][1<<n][h][w];
  memset(d,0,sizeof(d));
  for(int i=0,m; i<n; i++) {
    cin >> m;
    for(int j=0,x,y; j<m; j++) {
      cin >> x >> y;
      x--,y--;
      if(!j && x==sx && y==sy) t|=1<<i;
      v[i].push_back(P(x,y));
    }
  }
  d[0][t][sx][sy]=1;
  que.push((PP){0,t,sx,sy});
  while(!que.empty()) {
    PP p=que.front();que.pop();
    int kk=p.k,tt=p.t,nx=p.x,ny=p.y;
    if(tt==(1<<n)-1) {
      if(ans==-1) ans=kk;
      else ans=min(ans,kk);
      continue;
    }
    for(int i=0; i<9; i++) {
      int x=nx+dx[i],y=ny+dy[i],k=kk+1,t=tt,f=1;
      if(!check(h,w,x,y)) continue;
      for(int j=0; j<n; j++) {
        if(v[j][v[j].size()-1].first==x&&v[j][v[j].size()-1].second==y) f=0;
        if(t&(1<<j)) continue;
        if(v[j].size()-1<=k) f=0;
        else if(v[j][k].first==x&&v[j][k].second==y) t|=1<<j;
      }
      if(f && !d[k][t][x][y]) {
        d[k][t][x][y]=1;
        que.push((PP){k,t,x,y});
      }
    }
  }
  cout << ans << endl;
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3804
final_rank: 9

code_snippet: #include <iostream>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <iomanip>
using namespace std;

struct Point {
	int x, y;
};
vector<Point> path[5];
struct State {
	int x, y, t, bomb;
};

const int INF = 1 << 25;
int wf[300][300];


int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);

	int H, W, N, sx, sy;
	cin >> H >> W >> N >> sx >> sy;
	for(int i = 0; i < N; i++) {
		int l;
		cin >> l;
		path[i] = vector<Point>(l);
		for(int j = 0; j < l; j++) {
			cin >> path[i][j].x >> path[i][j].y;
		}
	}

	vector<int> order(N);
	for(int i = 0; i < N; i++) {
		order[i] = i;
	}

	int ans = INF;
	do {
		vector<State> states;
		states.push_back(State{ sx, sy, 0 });
		for(int i = 0; i < N; i++) {
			vector<Point>& p = path[order[i]];
			for(int t = 0; t < p.size() - 1; t++) {
				states.push_back(State{ p[t].x, p[t].y, t, i + 1 });
			}
		}

		for(int i = 0; i < 300; i++) {
			for(int j = 0; j < 300; j++) {
				wf[i][j] = (i == j) ? 0 : INF;
			}
		}

		int sn = states.size();
		for(int i = 0; i < sn; i++) {
			for(int j = 0; j < sn; j++) {
				State s1 = states[i], s2 = states[j];
				if(s1.bomb + 1 != s2.bomb) continue;
				if(s2.t - s1.t < max(abs(s1.x - s2.x), abs(s1.y - s2.y))) continue;
				wf[i][j] = s2.t - s1.t;
			}
		}

		for(int k = 0; k < sn; k++) {
			for(int i = 0; i < sn; i++) {
				for(int j = 0; j < sn; j++) {
					wf[i][j] = min(wf[i][j], wf[i][k] + wf[k][j]);
				}
			}
		}


		for(int i = 0; i < sn; i++) {
			if(states[i].bomb == N) {
				ans = min(ans, wf[0][i]);
			}
		}
	} while(next_permutation(order.begin(), order.end()));

	cout << ((ans == INF) ? -1 : ans) << endl;
}
accuracy: 0.275
time_ms: 10
memory_kb: 3548
final_rank: 20

code_snippet: #include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#define mod 1000000007
#define INF 1000000000
#define LLINF 2000000000000000000LL

#define SIZE 100000

int x2[7] ={0,1,2,4,8,16,32};
int mo[5] = {0,-1,0,1,0};
int mo8[9] = {0,1,1,-1,1,0,-1,-1,0};

int main(){
    int w,h,n;
    int sx,sy;
    int l,px,py;
    int mm[50][20][20]={0};
    int visit[50][20][20][32]={0};
    int bumb_x[5],bumb_y[5];
    
    scanf("%d%d%d%d%d",&w,&h,&n,&sx,&sy);
    
    sx--;
    sy--;
    
    for(int i=0;i<n;i++){
        scanf("%d",&l);
        
        for(int j=0;j<l;j++){
            scanf("%d%d",&px,&py);
            
            px--;
            py--;
            
            if(j<l-1){
                mm[j][py][px] |= 1 << i;
            }else{
                bumb_x[i] = px;
                bumb_y[i] = py;
            }
        }
    }
    
    queue<pair<int,pair<int,int> > > q1;
    
    q1.push({mm[0][sy][sx],{sx,sy}});
    
    for(int i=0;i<=h+w+3;i++){
        queue<pair<int,pair<int,int> > > q2;
        
        //cerr << i << endl;
        
        while(q1.size()){
            pair<int,pair<int,int> > p = q1.front();
            q1.pop();
            
            int nowv = p.first;
            int nowx = p.second.first;
            int nowy = p.second.second;
            
            //cerr << nowv << " " << nowx << " " << nowy << endl;
            
            bool flag = false;
            
            for(int j=0;j<n;j++){
                if(bumb_x[j] == nowx && bumb_y[j] == nowy) flag = true;
            }
            
            if(flag) continue;
            
            if(visit[i][nowx][nowy][nowv]) continue;
            visit[i][nowx][nowy][nowv] = true;
            
            if(nowv == (1<<n)-1){
                printf("%d\n",i);
                return 0;
            }
            
            for(int j=0;j<8;j++){
                int tox = nowx+mo8[j];
                int toy = nowy+mo8[j+1];
                
                if(0<=tox && tox<w && 0<=toy && toy<h)
                    q2.push({nowv|mm[i+1][toy][tox],{tox,toy}});
            }
            
            q2.push({nowv|mm[i+1][nowy][nowx],{nowx,nowy}});

        }
        
        q1 = q2;
    }
    
    puts("-1");
    
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 5800
final_rank: 11

code_snippet: #include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <functional>
#include <cassert>

typedef long long ll;
using namespace std;

#define mod 1000000007
#define INF 1000000000
#define LLINF 2000000000000000000LL

#define SIZE 100000

int x2[7] ={0,1,2,4,8,16,32};
int mo[5] = {0,-1,0,1,0};
int mo8[9] = {0,1,1,-1,1,0,-1,-1,0};

int main(){
    int w,h,n;
    int sx,sy;
    int l,px,py;
    int mm[50][20][20]={0};
    int visit[50][20][20][32]={0};
    int bumb_x[5],bumb_y[5];
    
    scanf("%d%d%d%d%d",&w,&h,&n,&sx,&sy);
    
    sx--;
    sy--;
    
    for(int i=0;i<n;i++){
        scanf("%d",&l);
        
        for(int j=0;j<l;j++){
            scanf("%d%d",&px,&py);
            
            px--;
            py--;
            
            if(j<l-1){
                mm[j][py][px] |= 1 << i;
            }else{
                bumb_x[i] = px;
                bumb_y[i] = py;
            }
        }
    }
    
    queue<pair<int,pair<int,int> > > q1;
    
    q1.push({mm[0][sy][sx],{sx,sy}});
    
    for(int i=0;i<=h+w+3;i++){
        queue<pair<int,pair<int,int> > > q2;
        
        //cerr << i << endl;
        
        while(q1.size()){
            pair<int,pair<int,int> > p = q1.front();
            q1.pop();
            
            int nowv = p.first;
            int nowx = p.second.first;
            int nowy = p.second.second;
            
            //cerr << nowv << " " << nowx << " " << nowy << endl;
            
            bool flag = false;
            
            for(int j=0;j<n;j++){
                if(bumb_x[j] == nowx && bumb_y[j] == nowy) flag = true;
            }
            
            if(flag) continue;
            
            if(visit[i][nowx][nowy][nowv]) continue;
            visit[i][nowx][nowy][nowv] = true;
            
            if(nowv == (1<<n)-1){
                printf("%d\n",i);
                return 0;
            }
            
            for(int j=0;j<8;j++){
                int tox = nowx+mo8[j];
                int toy = nowy+mo8[j+1];
                
                if(0<=tox && tox<w && 0<=toy && toy<h)
                    q2.push({nowv|mm[i+1][toy][tox],{tox,toy}});
            }
        }
        
        q1 = q2;
    }
    
    puts("-1");
    
    return 0;
}
accuracy: 0.45
time_ms: 10
memory_kb: 4544
final_rank: 16

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define MAX_H 20
#define MAX_W 20
#define MAX_N 5
#define MAX_S 40
#define INF 1e9

struct P{
    int x,y;
    P(){}
    P(int x,int y) : x(x),y(y) {}
};

struct State{
    int x,y,S,t;
    State(int x,int y,int S,int t) : x(x),y(y),S(S),t(t) {}
};

int H,W,N,L[MAX_N],b;
bool can[MAX_H][MAX_W];
bool dp[MAX_H][MAX_W][1<<MAX_N][MAX_S];
vector<P> path[MAX_N];
const int dx[9] = {-1,-1,-1,0,0,0,1,1,1};
const int dy[9] = {-1,0,1,-1,0,1,-1,0,1};

bool inField(int x,int y){
    return (0 <= x && x < W && 0 <= y && y < H);
}

int bfs(int sx,int sy){
    if(b == (1<<N)-1) return 0;
    queue<State> Q; Q.push(State(sx,sy,b,0));
    memset(dp,false,sizeof(dp));
    dp[sy][sx][b][0] = true;
    while(!Q.empty()){
        State s = Q.front(); Q.pop();
        int x = s.x,y = s.y,S = s.S;
        int t = s.t+1;
        bool ok = true;
        for(int i = 0 ; i < N ; i++){
            if(!(S >> i & 1) && L[i] <= s.t){
                ok = false;
                break;
            }
        }
        if(!ok) continue;
        if(S == (1<<N)-1) continue;
        for(int i = 0 ; i < 9 ; i++){
            int nx = x + dx[i];
            int ny = y + dy[i];
            if(!inField(nx,ny)) continue;
            if(!can[ny][nx]) continue;
            int nS = S;
            for(int j = 0 ; j < N ; j++){
                if(L[j] <= t) continue;
                P p = path[j][t];
                if(p.x == nx && p.y == ny){
                    nS |= 1<<j;
                }
            }
            if(!dp[ny][nx][nS][t]){
                dp[ny][nx][nS][t] = true;
                Q.push(State(nx,ny,nS,t));
            }
        }
    }
    int res = INF;
    for(int i = 0 ; i < H ; i++){
        for(int j = 0 ; j < W ; j++){
            for(int k = 1 ; k < H+W ; k++){
                if(dp[i][j][(1<<N)-1][k]){
                    res = min(res,k);
                }
            }
        }
    }
    return (res == INF ? -1 : res);
}

int main(){
 int sx,sy,x,y;
    cin >> W >> H >> N >> sx >> sy; sx--; sy--;
    fill(can[0],can[0]+MAX_H*MAX_W,1); b = 0;
    for(int i = 0 ; i < N ; i++){
        cin >> L[i]; path[i].resize(L[i]);
        for(int j = 0 ; j < L[i] ; j++){
            cin >> x >> y; x--; y--;
            path[i][j] = P(x,y);
            if(j == L[i]-1) can[y][x] = 0;
            if(j == 0 && x == sx && y == sy){
                b |= 1<<i;
            }
        }
    }
    cout << bfs(sx,sy) << endl;
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 1856
final_rank: 8

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define MAX_H 20
#define MAX_W 20
#define MAX_N 5
#define MAX_S 40
#define INF 1e9

struct P{
    int x,y;
    P(){}
    P(int x,int y) : x(x),y(y) {}
};

struct State{
    int x,y,S,t;
    State(int x,int y,int S,int t) : x(x),y(y),S(S),t(t) {}
};

int H,W,N,L[MAX_N],b;
bool can[MAX_H][MAX_W];
bool dp[MAX_H][MAX_W][1<<MAX_N][MAX_S];
vector<P> path[MAX_N];
const int dx[9] = {-1,-1,-1,0,0,0,1,1,1};
const int dy[9] = {-1,0,1,-1,0,1,-1,0,1};

bool inField(int x,int y){
    return (0 <= x && x < W && 0 <= y && y < H);
}

int bfs(int sx,int sy){
    if(b == (1<<N)-1) return 0;
    queue<State> Q; Q.push(State(sx,sy,b,0));
    memset(dp,false,sizeof(dp));
    dp[sy][sx][b][0] = true;
    while(!Q.empty()){
        State s = Q.front(); Q.pop();
        int x = s.x,y = s.y,S = s.S;
        int t = s.t;
        bool ok = true;
        for(int i = 0 ; i < N ; i++){
            if(!(S >> i & 1) && L[i] <= t){
                ok = false;
                break;
            }
        }
        if(!ok) continue;
        if(S == (1<<N)-1) continue;
        for(int i = 0 ; i < 9 ; i++){
            int nx = x + dx[i];
            int ny = y + dy[i];
            if(!inField(nx,ny)) continue;
            if(!can[ny][nx]) continue;
            int nS = S;
            for(int j = 0 ; j < N ; j++){
                if(L[j] <= t+1) continue;
                P p = path[j][t+1];
                if(p.x == nx && p.y == ny){
                    nS |= 1<<j;
                }
            }
            if(!dp[ny][nx][nS][s.t+1]){
                dp[ny][nx][nS][s.t+1] = true;
                Q.push(State(nx,ny,nS,s.t+1));
            }
        }
    }
    int res = INF;
    for(int i = 0 ; i < H ; i++){
        for(int j = 0 ; j < W ; j++){
            for(int k = 1 ; k < H+W ; k++){
                if(dp[i][j][(1<<N)-1][k]){
                    res = min(res,k);
                }
            }
        }
    }
    return (res == INF ? -1 : res);
}

int main(){
 int sx,sy,x,y;
    cin >> W >> H >> N >> sx >> sy; sx--; sy--;
    fill(can[0],can[0]+MAX_H*MAX_W,1); b = 0;
    for(int i = 0 ; i < N ; i++){
        cin >> L[i]; path[i].resize(L[i]);
        for(int j = 0 ; j < L[i] ; j++){
            cin >> x >> y; x--; y--;
            path[i][j] = P(x,y);
            if(j == L[i]-1) can[y][x] = 0;
            if(j == 0 && x == sx && y == sy){
                b |= 1<<i;
            }
        }
    }
    cout << bfs(sx,sy) << endl;
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 1860
final_rank: 3

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define MAX_H 20
#define MAX_W 20
#define MAX_N 5
#define MAX_S 40
#define INF 1e9

struct P{
    int x,y;
    P(){}
    P(int x,int y) : x(x),y(y) {}
};

struct State{
    int x,y,S,t;
    State(int x,int y,int S,int t) : x(x),y(y),S(S),t(t) {}
};

int H,W,N,L[MAX_N],b;
bool can[MAX_H][MAX_W];
bool dp[MAX_H][MAX_W][1<<MAX_N][MAX_S];
vector<P> path[MAX_N];
const int dx[9] = {-1,-1,-1,0,0,0,1,1,1};
const int dy[9] = {-1,0,1,-1,0,1,-1,0,1};

bool inField(int x,int y){
    return (0 <= x && x < W && 0 <= y && y < H);
}

int bfs(int sx,int sy){
    queue<State> Q; Q.push(State(sx,sy,b,0));
    memset(dp,false,sizeof(dp));
    dp[sy][sx][b][0] = true;
    while(!Q.empty()){
        State s = Q.front(); Q.pop();
        int x = s.x,y = s.y,S = s.S;
        int t = s.t;
        bool ok = true;
        for(int i = 0 ; i < N ; i++){
            if(!(S >> i & 1) && L[i] <= t){
                ok = false;
                break;
            }
        }
        if(!ok) continue;
        if(S == (1<<N)-1) continue;
        for(int i = 0 ; i < 9 ; i++){
            int nx = x + dx[i];
            int ny = y + dy[i];
            if(!inField(nx,ny)) continue;
            if(!can[ny][nx]) continue;
            int nS = S;
            for(int j = 0 ; j < N ; j++){
                if(L[j] <= t+1) continue;
                P p = path[j][t+1];
                if(p.x == nx && p.y == ny){
                    nS |= 1<<j;
                }
            }
            if(!dp[ny][nx][nS][s.t+1]){
                dp[ny][nx][nS][s.t+1] = true;
                Q.push(State(nx,ny,nS,s.t+1));
            }
        }
    }
    int res = INF;
    for(int i = 0 ; i < H ; i++){
        for(int j = 0 ; j < W ; j++){
            for(int k = 0 ; k < H+W ; k++){
                if(dp[i][j][(1<<N)-1][k]){
                    res = min(res,k);
                }
            }
        }
    }
    return (res == INF ? -1 : res);
}

int main(){
 int sx,sy,x,y;
    cin >> W >> H >> N >> sx >> sy; sx--; sy--;
    fill(can[0],can[0]+MAX_H*MAX_W,1); b = 0;
    for(int i = 0 ; i < N ; i++){
        cin >> L[i]; path[i].resize(L[i]);
        for(int j = 0 ; j < L[i] ; j++){
            cin >> x >> y; x--; y--;
            path[i][j] = P(x,y);
            if(j == L[i]-1) can[y][x] = 0;
            if(j == 0 && x == sx && y == sy){
                b |= 1<<i;
            }
        }
    }
    cout << bfs(sx,sy) << endl;
    return 0;
}
accuracy: 0.375
time_ms: 30
memory_kb: 1856
final_rank: 19

code_snippet: #include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<map>
#include<functional>
#include<stack>
#include<list>
#include<set>
#include<deque>
#include<climits>
using namespace std;
 
typedef long long ll;
 
const int dx[9] = {0, 1, 1, 1, 0, -1, -1, -1, 0};
const int dy[9] = {0, -1, 0, 1, 1, 1, 0, -1, -1};
 
bool dp[40][1 << 5][20][20];
 
int main(){
    int W, H, N, sx, sy, L[5];
    int px[5][40], py[5][40];
    cin >> W >> H >> N >> sx >> sy;
    sx--;
    sy--;
    for (int i = 0; i < N; i++)
    {
        cin >> L[i];
        for (int j = 0; j < L[i]; j++)
        {
            cin >> px[i][j] >> py[i][j];
            px[i][j]--;
            py[i][j]--;
        }
    }
 
    int ss = 0;
    for (int n = 0; n < N; n++)
    {
        if (px[n][0] == sx && py[n][0] == sy)
            ss = ss | (1 << n);
    }
    if (ss == (1 << N) - 1)
    {
        puts("0");
        return 0;
    }
    dp[0][ss][sy][sx] = true;
     
    for (int i = 0; i <= H + W; i++)
    {
        for (int j = 0; j < (1 << N) - 1; j++)
        {
            bool ng = false;
            for (int k = 0; k < N; k++)
            {
                if (((j >> k)&1) == 1) continue;
                if (L[k] - 2 - i <= 0) ng = true;
            }
            if (ng) continue;
            for (int k = 0; k < H; k++)
            {
                for (int l = 0; l < W; l++)
                {
                    if (!dp[i][j][k][l]) continue;
                    for (int m = 0; m < 9; m++)
                    {
                        int nx = l + dx[m];
                        int ny = k + dy[m];
                        int nj = j;
                        if(nx < 0 || W <= nx || ny < 0 || H <= ny) continue;
                        bool onBomb = false;
                        for (int n = 0; n < N; n++)
                        {
                            if (nx == px[n][L[n] - 1] && ny == py[n][L[n] - 1]) onBomb = true;
                            if (i+1 != L[n] - 1 && px[n][i+1] == nx && py[n][i+1] == ny)
                                nj = nj | (1 << n);
                        }
                        if (onBomb) continue;
                        if (nj == (1 << N) - 1)
                        {
                            printf("%d\n", i+1);
                            return 0;
                        }
                        dp[i+1][nj][ny][nx] = true;
                    }
                }
            }
        }
    }
 
    puts("-1");
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1608
final_rank: 1

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <utility>
#include <cstdlib>
#include <cstring>

using namespace std;
typedef pair<int, int> pii;
static const int dx[] = { 1, 1, 0, -1, -1, -1, 0, 1 };
static const int dy[] = { 0, -1, -1, -1, 0, 1, 1, 1 };
static const int INF = 1000000000;

static int mat[400][400];
static bool has_bomb[400];
static bool dp[6][41];

inline bool between(int a, int b, int c){
	return a <= b && b < c;
}

int main(){
	ios_base::sync_with_stdio(false);
	int w, h, n;
	cin >> w >> h >> n;
	for(int i = 0; i < h * w; ++i){
		for(int j = 0; j < h * w; ++j){ mat[i][j] = INF; }
		mat[i][i] = 0;
		has_bomb[i] = false;
	}
	int sx, sy;
	cin >> sx >> sy;
	--sx; --sy;
	vector<vector<pii>> paths(n);
	for(int i = 0; i < n; ++i){
		int l;
		cin >> l;
		for(int j = 0; j < l; ++j){
			int x, y;
			cin >> x >> y;
			--x; --y;
			paths[i].emplace_back(x, y);
		}
		const auto p = paths[i].back();
		has_bomb[p.second * w + p.first] = true;
	}
	for(int i = 0; i < h; ++i){
		for(int j = 0; j < w; ++j){
			if(has_bomb[i * w + j]){ continue; }
			for(int d = 0; d < 8; ++d){
				const int y = i + dy[d], x = j + dx[d];
				if(!between(0, y, h) || !between(0, x, w)){ continue; }
				if(has_bomb[y * w + x]){ continue; }
				mat[i * w + j][y * w + x] = 1;
			}
		}
	}
	for(int k = 0; k < w * h; ++k){
		for(int i = 0; i < w * h; ++i){
			for(int j = 0; j < w * h; ++j){
				mat[i][j] = min(mat[i][j], mat[i][k] + mat[k][j]);
			}
		}
	}
	sort(paths.begin(), paths.end());
	int answer = INF;
	do {
		memset(dp, 0, sizeof(dp));
		for(int i = 0; i + 1 < paths[0].size(); ++i){
			const auto &p = paths[0][i];
			const int d = mat[sy * w + sx][p.second * w + p.first];
			if(d <= i){ dp[1][i] = true; }
		}
		for(int i = 1; i < n; ++i){
			for(int j = 0; j + 1 < paths[i - 1].size(); ++j){
				if(!dp[i][j]){ continue; }
				const auto &s = paths[i - 1][j];
				for(int k = j; k + 1 < paths[i].size(); ++k){
					const auto &t = paths[i][k];
					const int d =
						mat[s.second * w + s.first][t.second * w + t.first];
					if(d <= k - j){ dp[i + 1][k] = true; }
				}
			}
		}
		for(int i = 0; i <= w + h; ++i){
			if(dp[n][i]){ answer = min(answer, i); }
		}
	} while(next_permutation(paths.begin(), paths.end()));
	if(answer >= INF){ answer = -1; }
	cout << answer << endl;
	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 1828
final_rank: 13