Problem:
運送会社
白虎運送は会津若松市を代表する運送会社です。昨今の原油価格の高騰は運送会社にも多大なダメージを与え、運送会社各社では、できるだけ少ないガソリンで荷物を運ぶことが課題となっています。
白虎運送では、重い荷物を積んだトラックは、その走りだしに多くのエネルギーを必要とすることに着目しました。トラックが倉庫を出発してから一度も停止することなく目的地まで到達する経路の中で最短時間の経路を通ることで、ガソリンの節約ができると考えました。
あなたの仕事は、このような最短経路を計算できるカーナビを開発することです。作成するカーナビ用プログラムの仕様は以下のとおりです。
市内は、下図のように、東西方向の道路
M
本、南北方向の道路
N
本 からなる格子で表し、格子の各交点は交差点を表します。
交差点のいくつかには東西 - 南北の方向に信号機が設置されており、一定の周期で青、赤のシグナルが点灯しています。
市内の交差点間を結ぶ道路には工事中で通過できない個所がいくつかあります。
トラックが交差点から交差点へ移動するのに必要な時間は一定ですが、渋滞している道路ではさらに長い時間がかかります。
市内の道路情報、トラックが交差点間を移動するのに必要な時間、信号機がある交差点と各信号機の周期、工事中の道路、渋滞している道路と渋滞度、白虎運送の倉庫(始点)と目的地(終点)の位置を入力とし、始点から終点までの最短の時間を出力するプログラムを作成して下さい。
図のように、東西の方向の道路はa、b、c、... と英小文字で名前が付けられ 、南北の方向の道路は 1、2、3、... と整数で名前が付けられています。市内の交差点は、これらの英小文字と整数の組み合わせ
H
-
V
で指定されます。
例えば、市内の最北西の交差点は a-1 で指定されます。各信号は周期
k
をもち、
k
分ごとに切り替わります。東西が青ならば南北が赤で、南北が青ならば東西が赤です。黄色のシグナルは存在しません。トラックは二つの交差点を結ぶ道路を移動するのに
D
分要しますが、その道路が渋滞している場合はさらに
d
分の時間を要します。トラックは道路が工事中の場合は移動できません。
また、交差点に到達した時刻に、信号が赤の場合には進入できません。トラックは交差点でのみ、東、西、南、北に方向を変えることができますが、来た方向へは移動(Uターン)できません。道路は2方通行であり、トラックが行き来する時間、工事状況、渋滞度は2方向共通です。
初期状態として、トラックは東を向いていて、トラックが倉庫を出発する瞬間すべての信号機が南北の方向に青に切り替わるものとします。また、トラックは 100分以内で目的地に到達できるものとします。
Input
複数のデータセットの並びが入力として与えられます。入力の終わりはゼロふたつの行で示されます。各データセットは以下の形式で与えられます。
M
N
D
ns
H
1
-
V
1
k
1
H
2
-
V
2
k
2
:
H
ns
-
V
ns
k
ns
nc
H
11
-
V
11
H
12
-
V
12
H
21
-
V
21
H
22
-
V
22
:
H
nc1
-
V
nc1
H
nc2
-
V
nc2
nj
H
11
-
V
11
H
12
-
V
12
d
1
H
21
-
V
21
H
22
-
V
22
d
2
:
H
nj1
-
V
nj1
H
nj2
-
V
nj2
d
nj
H
s
-
V
s
H
d
-
V
d
１行目に道路の本数
M
,
N
(2 ≤
M, N
≤ 20) が与えられます。２行目に、二つの交差点を結ぶ道路を移動するのに要する時間
D
(1 ≤
D
≤ D, 整数) が与えられます。
３行目に信号機の数
ns
が与えられます。続く
ns
行に、
i
個目の信号機の位置を表す英小文字と整数の組
H
i
-
V
i
と周期
k
(1 ≤
k
≤ 100) が与えられます。
続く行に、工事中の道路の数
nc
が与えられます。続く
nc
行に、
i
個目の工事中の道路の２つの端点（交差点）を表す英小文字と整数の組
H
i1
-
V
i1
H
i2
-
V
i2
が与えられます。
続く行に、渋滞道路の数
nj
が与えられます。続く
nj
行に、
i
個目の渋滞道路の２つの端点（交差点）を表す英小文字と整数の組
H
i1
-
V
i1
H
i2
-
V
i2
と時間
d
i
(1 ≤
d
i
≤ 100) が与えられます。
最後の行に、始点の交差点
H
s
-
V
d
と終点の交差点
H
d
-
V
d
が与えられます。
データセットの数は 20 を超えません。
Output
データセット毎に最短時間を１行に出力します。
Sample Input
4 5
1
3
b-2 3
c-3 2
c-4 1
3
a-2 b-2
b-3 c-3
d-3 d-4
2
b-3 b-4 1
c-1 d-1 1
d-1 b-4
4 5
1
3
b-2 3
c-3 2
c-4 1
3
a-2 b-2
b-3 c-3
d-3 d-4
2
b-3 b-4 1
c-1 d-1 1
d-2 b-4
4 5
1
3
b-2 3
c-3 2
c-4 1
3
a-2 b-2
b-3 c-3
d-3 d-4
2
b-3 b-4 1
c-1 d-1 1
d-3 b-4
0 0
Output for the Sample Input
7
4
8

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
template<class T> using rpriority_queue = priority_queue<T, vector<T>, greater<T>>;

void debug(vector<vector<int>> A){
    for(int y = 0; y < A.size(); y++){
        for(int x = 0; x < A[y].size(); x++){
            cerr << A[y][x] << (x + 1 == A[y].size() ? '\n' : ' ');
        }
    }
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int h, w;
    vector<pair<int,int>> dir = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
    while(cin >> h >> w, h){
        auto f = [&](string s){
            return make_pair(s[0] - 'a', stoi(s.substr(2, s.size() - 2)) - 1);
        };
        int D, ns, nc, nj, y, x, y1, x1, y2, x2, v, sy, sx, gy, gx, ds, is, d, dy, dx, ans = 1 << 30;
        string s, t;
        cin >> D >> ns;
        //信号機と周期
        //時刻tに対して t mod 2 * S[y][x] < S[y][x]のとき南北方向
        //そうでないとき東西方向
        vector<vector<int>> S(h, vector<int>(w));
        vector<vector<vector<vector<int>>>> K(h, vector<vector<vector<int>>>(w, 
                    vector<vector<int>>(h, vector<int>(w))));
        vector<vector<vector<vector<int>>>> J(h, vector<vector<vector<int>>>(w, 
                    vector<vector<int>>(h, vector<int>(w))));
        for(int i = 0; i < ns; i++){
            cin >> s >> v;
            tie(y, x) = f(s);
            S[y][x] = v;
        }
        cin >> nc;
        for(int i = 0; i < nc; i++){
            cin >> s >> t;
            tie(y1, x1) = f(s);
            tie(y2, x2) = f(t);
            K[y1][x1][y2][x2] = K[y2][x2][y1][x1] = 1;
        }
        cin >> nj;
        for(int i = 0; i < nj; i++){
            cin >> s >> t >> v;
            tie(y1, x1) = f(s);
            tie(y2, x2) = f(t);
            J[y1][x1][y2][x2] = J[y2][x2][y1][x1] = v;
        }
        cin >> s >> t;
        tie(sy, sx) = f(s);
        tie(gy, gx) = f(t);

        //交差点に入る  :0~3
        //交差点から出る:4~7
        //0, 2:東西方向
        //1, 3:南北方向
        vector<vector<vector<vector<bool>>>> dp(101,
               vector<vector<vector<bool>>>(8, 
               vector<vector<bool>>(h, 
               vector<bool>(w))));
        dp[0][0][sy][sx] = true;
        for(int i = 0; i <= 100; i++){
            for(int j = 0; j < 8; j++){
                if(j & 4){
                    tie(dy, dx) = dir[j - 4];
                    for(int y = 0; y < h; y++){
                        for(int x = 0; x < w; x++){
                            if(!dp[i][j][y][x])continue;
                            if(y + dy < 0 || x + dx < 0 || y + dy >= h || x + dx >= w)continue;
                            if(K[y][x][y + dy][x + dx])continue;
                            int nt = i + D + J[y][x][y + dy][x + dx];
                            if(nt > 100)continue;
                            dp[nt][j - 4][y + dy][x + dx] = true;
                        }
                    }
                }else{
                    for(int y = 0; y < h; y++){
                        for(int x = 0; x < w; x++){
                            if(!dp[i][j][y][x])continue;
                            if(S[y][x]){
                                if(j & 1){
                                    if(i % (2 * S[y][x]) >= S[y][x])continue;
                                }else{
                                    if(i % (2 * S[y][x]) < S[y][x])continue;
                                }
                            }
                            for(int k = 0; k < 4; k++){
                                if(abs(j - k) == 2)continue;
                                dp[i][k + 4][y][x] = true;
                            }
                        }
                    }
                }
            }
        }
        for(int i = 0; i <= 100; i++){
            for(int j = 0; j < 8; j++){
                if(dp[i][j][gy][gx])ans = min(ans, i);
            }
        }
        cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 10
memory_kb: 6500
final_rank: 19

code_snippet: #include<iostream>
#include<queue>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
int H,W,D;
int rd()
{
	char c;cin>>c;
	int ret=(c-'a')*W;
	cin>>c;
	int y;cin>>y;
	return ret+y-1;
}
int k[400];
bool vis[400][101][4];
int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
main()
{
	while(cin>>H>>W,H)
	{
		cin>>D;
		{
			for(int i=0;i<H*W;i++)k[i]=0;
			int ns;
			cin>>ns;
			for(;ns--;)
			{
				int id=rd();
				cin>>k[id];
			}
		}
		map<pair<int,int>,int>d;
		{
			int nc;cin>>nc;
			for(;nc--;)
			{
				int x,y;
				x=rd();
				y=rd();
				pair<int,int>p=minmax(x,y);
				d[p]=-1;
			}
		}
		{
			int nj;cin>>nj;
			for(;nj--;)
			{
				int x,y;
				x=rd();
				y=rd();
				pair<int,int>p=minmax(x,y);
				cin>>d[p];
			}
		}
		for(int i=0;i<H*W;i++)for(int k=0;k<=100;k++)for(int j=0;j<4;j++)vis[i][k][j]=false;
		int start,goal;
		start=rd();goal=rd();
		queue<pair<int,pair<int,int> > >P;
		P.push(make_pair(0,make_pair(start,2)));
		vis[start][0][2]=true;
		while(!P.empty())
		{
			int cost=P.front().first;
			int now=P.front().second.first,dir=P.front().second.second;
			P.pop();
			int nx=now/W,ny=now%W;
			for(int r=0;r<4;r++)if(dir!=(r^1))
			{
				int tx=nx+dx[r],ty=ny+dy[r];
				if(tx<0||ty<0||tx>=H||ty>=W)continue;
				int nxt=tx*W+ty;
				pair<int,int>p=minmax(now,nxt);
				if(d[p]<0)continue;
				int nc=cost+D+d[p];
				if(k[nxt]>0)
				{
					int wi=nc%(2*k[nxt])/k[nxt];
					if(wi==0&&r>=2||wi==1&&r<2)continue;
				}
				if(nc<=100&&!vis[nxt][nc][r])
				{
					vis[nxt][nc][r]=true;
					P.push(make_pair(nc,make_pair(nxt,r)));
				}
			}
		}
		int ans=1e9;
		for(int k=0;k<=100;k++)for(int r=0;r<4;r++)if(vis[goal][k][r])ans=min(ans,k);
		cout<<ans<<endl;
	}
}
accuracy: 1
time_ms: 30
memory_kb: 3276
final_rank: 15

code_snippet: #include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <cmath>

static const int MOD = 1000000007;
using ll = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using namespace std;

template<class T> constexpr T INF = ::numeric_limits<T>::max()/32*15+208;

template <class T, class U>
vector<T> make_v(U size, const T& init){ return vector<T>(static_cast<size_t>(size), init); }

template<class... Ts, class U>
auto make_v(U size, Ts... rest) { return vector<decltype(make_v(rest...))>(static_cast<size_t>(size), make_v(rest...)); }

template<class T> void chmin(T &a, const T &b){ a = (a < b ? a : b); }
template<class T> void chmax(T &a, const T &b){ a = (a > b ? a : b); }

void solve(int n, int m){
    int d, ns;
    cin >> d >> ns;
    map<int, int> kousaten;
    map<pair<int, int>, int> G;
    for (int i = 0; i < ns; ++i) {
        char a; int b, k;
        scanf(" %c-%d %d", &a, &b, &k);
        kousaten[(a-'a'+1)*m+b] = k;
    }
    int nc;
    cin >> nc;
    for (int i = 0; i < nc; ++i) {
        char a, aa; int b, bb;
        scanf(" %c-%d %c-%d", &a, &b, &aa, &bb);
        G[{(a-'a'+1)*m+b, (aa-'a'+1)*m+bb}] = 200;
        G[{(aa-'a'+1)*m+bb, (a-'a'+1)*m+b}] = 200;
    }
    int nj;
    cin >> nj;
    for (int i = 0; i < nj; ++i) {
        char a, aa; int b, bb, D;
        scanf(" %c-%d %c-%d %d", &a, &b, &aa, &bb, &D);
        G[{(a-'a'+1)*m+b, (aa-'a'+1)*m+bb}] = d+D;
        G[{(aa-'a'+1)*m+bb, (a-'a'+1)*m+b}] = d+D;
    }
    int sy, sx, gy, gx;
    {
        char a, aa; int b, bb;
        scanf(" %c-%d %c-%d", &a, &b, &aa, &bb);
        sy = a-'a'+1, sx = b, gy = aa-'a'+1, gx = bb;
    }
    auto v = make_v(n+2, m+2, 0);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            v[i+1][j+1] = 1;
        }
    }
    array<int, 4> dy{-1, 1, 0, 0}, dx{0, 0, -1, 1};
    auto dp = make_v(n+2, m+2, 101, 4, 0);
    auto dfs = [&](int y, int x, int t, int kk, auto &&f) -> void {
        for (int k = 0; k < 4; ++k) {
            int yy = y+dy[k], xx = x+dx[k];
            if(!v[yy][xx] || k == (kk^1)) continue;

            if(kousaten.count(yy*m+xx)){
                int K = kousaten[yy*m+xx];
                int D = G.count({y*m+x, yy*m+xx}) ? G[{y*m+x, yy*m+xx}] : d;
                if(t+D <= 100 && !dp[yy][xx][t+D][kk] && !(((t+D)%(2*K) < K)^(k < 2))){
                    dp[yy][xx][t+D][kk] = 1;
                    f(yy, xx, t+D, k, f);
                }
            }else {
                int D = G.count({y*m+x, yy*m+xx}) ? G[{y*m+x, yy*m+xx}] : d;
                if(t+D <= 100 && !dp[yy][xx][t+D][kk]){
                    dp[yy][xx][t+D][kk] = 1;
                    f(yy, xx, t+D, k, f);
                }
            }

        }
    };
    dp[sy][sx][0][3] = 1;
    dfs(sy, sx, 0, 3, dfs);
    for (int i = 0; i <= 100; ++i) {
        for (int k = 0; k < 4; ++k) {
            if(dp[gy][gx][i][k]){
                cout << i << "\n";
                return;
            }
        }
    }
}

int main() {
    int n, m;
    while(cin >> n >> m, n){
        solve(n, m);
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 6056
final_rank: 17

code_snippet: #include <cstdio>
#include <cstdlib>
#include <vector>
#include <queue>
using namespace std;

typedef pair<int, int> P;
typedef pair<int, P> PP;
typedef pair<int, PP> PPP;
typedef pair<int, PPP> E;
typedef priority_queue<E, vector<E>, greater<E> > Q;

int M, N, D;
int sr, sc;
int gr, gc;
int cost_c[19][20];
int cost_r[20][19];
int signal[20][20];
bool used[101][4][20][20];
const int INF = 10000000;

bool input() {
  scanf("%d %d\n", &M, &N);
  if (!M && !N) {
    return false;
  }
  scanf("%d\n", &D);
  for (int i = 0; i < M - 1; ++i) {
    for (int j = 0; j < N; ++j) {
      cost_c[i][j] = D;
    }
  }
  for (int i = 0; i < M; ++i) {
    for (int j = 0; j < N - 1; ++j) {
      cost_r[i][j] = D;
    }
  }
  for (int i = 0; i < M; ++i) {
    for (int j = 0; j < N; ++j) {
      signal[i][j] = -1;
    }
  }
  int ns;
  scanf("%d\n", &ns);
  for (int i = 0; i < ns; ++i) {
    char a;
    int r, c, k;
    scanf("%c-%d %d\n", &a, &c, &k);
    r = a - 'a';
    --c;
    signal[r][c] = k;
  }
  int nc;
  scanf("%d\n", &nc);
  for (int i = 0; i < nc; ++i) {
    char a1, a2;
    int r1, c1, r2, c2;
    scanf("%c-%d %c-%d\n", &a1, &c1, &a2, &c2);
    r1 = a1 - 'a';
    r2 = a2 - 'a';
    --c1;
    --c2;
    if (r1 == r2) {
      cost_r[r1][min(c1, c2)] = INF;
    } else if (c1 == c2) {
      cost_c[min(r1, r2)][c1] = INF;
    }
  }
  int nj;
  scanf("%d\n", &nj);
  for (int i = 0; i < nj; ++i) {
    char a1, a2;
    int r1, c1, r2, c2, d;
    scanf("%c-%d %c-%d %d\n", &a1, &c1, &a2, &c2, &d);
    r1 = a1 - 'a';
    r2 = a2 - 'a';
    --c1;
    --c2;
    if (r1 == r2) {
      cost_r[r1][min(c1, c2)] += d;
    } else if (c1 == c2) {
      cost_c[min(r1, r2)][c1] += d;
    }
  }
  {
    char c;
    scanf("%c-%d\n", &c, &sc);
    sr = c - 'a';
    --sc;
  }
  {
    char c;
    scanf("%c-%d\n", &c, &gc);
    gr = c - 'a';
    --gc;
  }
  for (int t = 0; t <= 100; ++t) {
    for (int d = 0; d < 4; ++d) {
      for (int i = 0; i < M; ++i) {
        for (int j = 0; j < N; ++j) {
          used[t][d][i][j] = false;
        }
      }
    }
  }
  return true;
}

bool can_go(int t, int k, bool row) {
  int h = t / k;
  if (row) {
    return h & 1;
  } else {
    return !(h & 1);
  }
}

int solve() {
  PP s = PP(0, P(sr, sc));
  int h0 = (abs(sr - gr) + abs(sc - gc)) * D;
  Q q;
  q.push(E(h0, PPP(0, s)));
  int ans = -1;
  while (!q.empty()) {
    E cur = q.top();
    q.pop();
    PPP ppp = cur.second;
    int t = ppp.first;
    PP pp = ppp.second;
    int d = pp.first;
    P p = pp.second;
    int r = p.first;
    int c = p.second;
    if (r == gr && c == gc) {
      ans = t;
      break;
    }
    if (used[t][d][r][c]) {
      continue;
    }
    used[t][d][r][c] = true;
    if (r > 0 && d != 2) {
      int nt = t + cost_c[r - 1][c];
      if (nt < INF && (signal[r - 1][c] < 0 || can_go(nt, signal[r - 1][c], false))) {
        int h = (abs(r - 1 - gr) + abs(c - gc)) * D;
        q.push(E(nt + h, PPP(nt, PP(3, P(r - 1, c)))));
      }
    }
    if (r < M - 1 && d != 3) {
      int nt = t + cost_c[r][c];
      if (nt < INF && (signal[r + 1][c] < 0 || can_go(nt, signal[r + 1][c], false))) {
        int h = (abs(r + 1 - gr) + abs(c - gc)) * D;
        q.push(E(nt + h, PPP(nt, PP(2, P(r + 1, c)))));
      }
    }
    if (c > 0 && d != 0) {
      int nt = t + cost_r[r][c - 1];
      if (nt < INF && (signal[r][c - 1] < 0 || can_go(nt, signal[r][c - 1], true))) {
        int h = (abs(r - gr) + abs(c - 1 - gc)) * D;
        q.push(E(nt + h, PPP(nt, PP(1, P(r, c - 1)))));
      }
    }
    if (c < N - 1 && d != 1) {
      int nt = t + cost_r[r][c];
      if (nt < INF && (signal[r][c + 1] < 0 || can_go(nt, signal[r][c + 1], true))) {
        int h = (abs(r - gr) + abs(c + 1 - gc)) * D;
        q.push(E(nt + h, PPP(nt, PP(0, P(r, c + 1)))));
      }
    }
  }
  return ans;
}

int main() {
  while (input()) {
    int ans = solve();
    printf("%d\n", ans);
  }
}
accuracy: 1
time_ms: 10
memory_kb: 2852
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, -1, 0, 1};
const int INF = 1 << 28;
inline pair<int, int> inputPos(){
	string str;
	cin >> str;
	return pair<int, int>(str[0] - 'a', atoi(str.c_str() + 2) - 1);
}

int m, n;
int D;
int sign[20][20];
int cant[20][20][20][20];
int cst[20][20][20][20];
pair<int, int> sp, gp;

bool ok(int x, int y){
	return x >= 0 && x < m && y >= 0 && y < n;
}

void solve()
{
	static int dist[101][20][20][4];
	fill_n(***dist, 101 * 20 * 20 * 4, INF);
	dist[0][sp.first][sp.second][3] = 0;
	for (int t = 0; t < 100; t++){
		for (int x = 0; x < m; x++){
			for (int y = 0; y < n; y++){
				for (int d = 0; d < 4; d++){
					if (dist[t][x][y][d] == INF) continue;
					for (int dd = 3; dd <= 5; dd++){
						int dir = (d + dd) % 4;
						int nx = x + dx[dir];
						int ny = y + dy[dir];
						if (!ok(nx, ny)) continue;
						if (cant[x][y][nx][ny]) continue;
						int nt = t + D + cst[x][y][nx][ny];
						if (nt > 100) continue;
						if (sign[nx][ny]){
							if ((nt / sign[nx][ny] + dir) % 2 == 1){
								continue;
							}
						}
						dist[nt][nx][ny][dir] = min(dist[nt][nx][ny][dir], nt);
					}
				}
			}
		}
	}
	
	for (int t = 0; ; t++){
		for (int d = 0; d < 4; d++){
			if (dist[t][gp.first][gp.second][d] < INF){
				printf("%d\n", dist[t][gp.first][gp.second][d]);
				return;
			}
		}
	}
}

int main()
{
	while (scanf("%d %d", &m, &n), m){
		memset(sign, 0, sizeof(sign));
		memset(cant, 0, sizeof(cant));
		memset(cst, 0, sizeof(cst));
		
		scanf("%d", &D);
		
		int ns;
		scanf("%d", &ns);
		for (int i = 0; i < ns; i++){
			pair<int, int> pos = inputPos();
			int k;
			scanf("%d", &k);
			sign[pos.first][pos.second] = k;
		}
		
		int nc;
		scanf("%d", &nc);
		for (int i = 0; i < nc; i++){
			pair<int, int> pos1 = inputPos();
			pair<int, int> pos2 = inputPos();
			cant[pos1.first][pos1.second][pos2.first][pos2.second] = true;
			cant[pos2.first][pos2.second][pos1.first][pos1.second] = true;
		}
		
		int nj;
		scanf("%d", &nj);
		for (int i = 0; i < nj; i++){
			pair<int, int> pos1 = inputPos();
			pair<int, int> pos2 = inputPos();
			int d;
			scanf("%d", &d);
			cst[pos1.first][pos1.second][pos2.first][pos2.second] += d;
			cst[pos2.first][pos2.second][pos1.first][pos1.second] += d;
		}
		
		sp = inputPos();
		gp = inputPos();
		
		solve();
	}
}
accuracy: 1
time_ms: 10
memory_kb: 3104
final_rank: 13

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

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)

using namespace std;

typedef pair<int,int> ii;

struct Data {
  int cur, dir, time;
  bool operator < ( const Data &data ) const {
    if( time != data.time ) return time > data.time;
    if( dir != data.dir ) return dir > data.dir;
    return cur > data.cur;
  }
};

int w,h,D,sp,ep;
int field[30][30];
map<ii,int> coef;
set<ii> S;
vector<int> wigwag;
bool visited[500][110][4];
int dx[] = {0,1,0,-1};
int dy[] = {1,0,-1,0};

bool isValid(int x,int y) { return 0 <= x && x < w && 0 <= y && y < h; }

int getPoint(string s){
  rep(i,s.size()) if( s[i] == '-' ) { s[i] = ' '; break; }
  stringstream ss;
  ss << s;
  string temp[2];
  ss >> temp[0] >> temp[1];
  int x = (atoi)(temp[1].c_str());
  int y = temp[0][0] - 'a';
  --x;
  return x + y * w;
}

void compute(){
  rep(i,h*w) rep(j,110) rep(k,4) visited[i][j][k] = false;
  visited[sp][0][1] = true;
  priority_queue<Data> Q;
  Q.push((Data){sp,1,0});
  while( !Q.empty() ){
    Data data = Q.top(); Q.pop();
    if( data.cur == ep ) { cout << data.time << endl; return; }
    rep(i,4) if( (data.dir+2)%4 != i ){
      int nx = data.cur % w + dx[i], ny = data.cur / w + dy[i];
      int next = nx + ny * w;
      if( !isValid(nx,ny) ) continue;
      ii coor = ii(data.cur,next);
      if( coor.first > coor.second ) swap(coor.first,coor.second);
      if( S.count(coor) ) continue;
      int ntime = data.time + D + coef[coor];
      if( ntime > 100 ) continue;

      if( field[ny][nx] != -1 ) {
        bool failed = false;
        int cycle = wigwag[field[ny][nx]];
        int now   = ntime / cycle;
        //cout << nx << "," << ny << " " << cycle << " and " << now << " ndir = " << i<< endl;
        if( now & 1 ) {
          if( i == 0 || i == 2 ) failed = true;
        } else {
          if( i == 1 || i == 3 ) failed = true;
        }
        if( failed ) continue;
      }
      
      if( !visited[next][ntime][i] ){
        //cout << coor.first << " < " << coor.second << endl;
        //cout << ntime << " : (" << data.cur % w << "," << data.cur / w << ") " << data.dir << " => (" << nx << "," << ny << ") dir = " << i << endl; 
        visited[next][ntime][i] = true;
        Q.push((Data){next,i,ntime});
      }
      
    }
  }
}

int main(){
  while( cin >> h >> w, w|h ){
    cin >> D;
    rep(i,h) rep(j,w) field[i][j] = -1;
    wigwag.clear();
    int temp;
    cin >> temp;
    wigwag.resize(temp);
    rep(i,temp) {
      string s;
      int k;
      cin >> s >> k;
      rep(j,s.size()) if( s[j] == '-' ) { s[j] = ' '; break; }
      stringstream ss;
      ss << s;
      string stemp[2];
      ss >> stemp[0] >> stemp[1];
      int x = (atoi)(stemp[1].c_str());
      int y = stemp[0][0] - 'a';
      --x;
      field[y][x] = wigwag.size();
      wigwag.push_back(k);
    }
    
    S.clear();
    cin >> temp;
    rep(i,temp){
      string s,s2;
      cin >> s >> s2;
      int p1 = getPoint(s), p2 = getPoint(s2);
      if( p1 > p2 ) swap(p1,p2);
      S.insert(ii(p1,p2));
    }

    coef.clear();
    cin >> temp;
    rep(i,temp){
      string s,s2;
      int itemp;
      cin >> s >> s2 >> itemp;
      int p1 = getPoint(s), p2 = getPoint(s2);
      if( p1 > p2 ) swap(p1,p2);
      coef[ii(p1,p2)] = itemp;
    }

    string ssp,sep;
    cin >> ssp >> sep;
    sp = getPoint(ssp);
    ep = getPoint(sep);

    compute();

  }
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 1516
final_rank: 6

code_snippet: #include <iostream>
#include <queue>
#include <algorithm>
#include <string>
#include <utility>
#include <cstdio>
using namespace std;

// inputs
int N, M;
int D;
int ns, nc, nj;

const int margin = 2;
bool visited[32][32][128][4];
int map[64][64];

struct status {
	int x, y;
	int t;
	int d;
	status() {}
	status(int x_, int y_, int t_, int d_) {
		x = x_; y = y_; t = t_; d = d_;
	}
	bool operator<(const status obj) const {
		return this->t > obj.t;
	}
};

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

int gcd(int a, int b) {
	return a % b == 0 ? b : gcd(b, a % b);
}
int lcm(int a, int b) {
	return a * b / gcd(a, b);
}

pair<int,int> to_coord(string s) {
	string tmp(s.begin() + 2, s.end());
	int x = 0;
	for(int i = 0; i < tmp.size(); i++) {
		x *= 10;
		x += tmp[i] - '0';
	}
	return pair<int,int>(x - 1, s[0] - 'a');
}

int main() {
	while(cin >> M >> N, M || N) {
		cin >> D;
		for(int i = 0; i < 64; i++)
			for(int j = 0; j < 64; j++)
				map[i][j] = -1;
		for(int i = 0; i < M; i++) {
			for(int j = 0; j < N; j++) {
				map[i*2 + margin][j%(N-1)*2+1 + margin] = D;
				map[i%(M-1)*2+1 + margin][j*2 + margin] = D;
			}
		}
		for(int i = 0; i < 32; i++)
			for(int j = 0; j < 32; j++)
				for(int k = 0; k < 128; k++)
					for(int l = 0; l < 4; l++)
						visited[i][j][k][l] = false;
		cin >> ns;
		for(int i = 0; i < ns; i++) {
			string tmp;
			int k;
			pair<int,int> coord;
			cin >> tmp >> k;
			coord = to_coord(tmp);
			map[coord.second * 2 + margin][coord.first * 2 + margin] = k;
		}
		cin >> nc;
		for(int i = 0; i < nc; i++) {
			string tmp0, tmp1;
			pair<int,int> coord0, coord1;
			cin >> tmp0 >> tmp1;
			coord0 = to_coord(tmp0);
			coord1 = to_coord(tmp1);
			map[coord0.second + coord1.second + margin][coord0.first + coord1.first + margin] = -1;
		}
		cin >> nj;
		for(int i = 0; i < nj; i++) {
			string tmp0, tmp1;
			int d;
			pair<int,int> coord0, coord1;
			cin >> tmp0 >> tmp1 >> d;
			coord0 = to_coord(tmp0);
			coord1 = to_coord(tmp1);
			map[coord0.second + coord1.second + margin][coord0.first + coord1.first + margin] = D + d;
		}

		/*
		for(int i = 0; i < 32; i++) {
			for(int j = 0; j < 32; j++) {
				if(map[i][j] < 0)
					printf(" x");
				else
					printf("% 2d", map[i][j]);
			}
			putchar('\n');
		}
		// */

		string start_str, goal_str;
		pair<int,int> start, goal;
		cin >> start_str >> goal_str;
		start = to_coord(start_str);
		goal = to_coord(goal_str);

		// dijkstra
		priority_queue<status> q;
		q.push(status(start.first, start.second, 0, 1));
		visited[start.second][start.first][0][1] = true;

		while(!q.empty()) {
			status cur;
			cur = q.top(); q.pop();
		//	cout << cur.x << " " << cur.y << " " << cur.t << endl;
			if(cur.x == goal.first && cur.y == goal.second) {
				cout << cur.t << endl;
				break;
			}

			for(int i = 0; i < 4; i++) {
				bool flg = true;
				flg &= !(map[cur.y * 2 + dy[i] + margin][cur.x * 2 + dx[i] + margin] < 0);
				flg &= !visited[cur.y + dy[i]][cur.x + dx[i]][cur.t + map[cur.y * 2 + dy[i] + margin][cur.x* 2 + dx[i] + margin]][i];
				flg &= dx[i]*dx[cur.d] + dy[i]*dy[cur.d] >= 0;
				flg &= (map[(cur.y + dy[i]) * 2 + margin][(cur.x + dx[i]) * 2 + margin] < 0)
					|| (((cur.t + map[cur.y * 2 + dy[i] + margin][cur.x * 2 + dx[i] + margin]) / map[(cur.y + dy[i]) * 2 + margin][(cur.x + dx[i]) * 2 + margin]) % 2
							== !(i / 2));
				if(flg) {
					q.push(status(cur.x + dx[i], cur.y + dy[i], cur.t + map[cur.y * 2 + dy[i] + margin][cur.x * 2 + dx[i] + margin], i));
					visited[cur.y + dy[i]][cur.x + dx[i]][cur.t + map[cur.y * 2 + dy[i] + margin][cur.x * 2 + dx[i] + margin]][i] = true;
				}
			}
		}
	}
}
accuracy: 1
time_ms: 10
memory_kb: 1800
final_rank: 7

code_snippet: #include<iostream>
#include<tuple>
#include<set>

using namespace std;

int main(){
  for(int M,N;cin>>M>>N,M;){
    int D,ns;
    cin>>D>>ns;
    int k[21][21]={};
    for(int i=0;i<ns;i++){
      char H,d;
      int V;
      cin>>H>>d>>V;
      cin>>k[H-'a'][V];
    }
    int nc;
    cin>>nc;
    bool uc[21][21][21][21]={};
    while(nc--){
      char H1,d1,H2,d2;
      int V1,V2;
      cin>>H1>>d1>>V1>>H2>>d2>>V2;
      uc[H1-'a'][V1][H2-'a'][V2]=uc[H2-'a'][V2][H1-'a'][V1]=true;
    }
    int nj;
    cin>>nj;
    int jam[21][21][21][21]={};
    while(nj--){
      char H1,d1,H2,d2;
      int V1,V2,d;
      cin>>H1>>d1>>V1>>H2>>d2>>V2>>d;
      jam[H1-'a'][V1][H2-'a'][V2]=jam[H2-'a'][V2][H1-'a'][V1]=d;
    }
    char H1,d1,H2,d2;
    int V1,V2;
    cin>>H1>>d1>>V1>>H2>>d2>>V2;
    set<tuple<int,int,int,int> > s;
    s.insert(make_tuple(0,H1-'a',V1,1));
    for(auto e:s){
      if(get<1>(e)==H2-'a'&&get<2>(e)==V2){
	cout<<get<0>(e)<<endl;
	break;
      }
      for(int i=1;i<=3;i++){
	int nd=(get<3>(e)+i+2)%4;
	static int dy[]={-1,0,1,0};
	static int dx[]={0,1,0,-1};
	int sy=get<1>(e);
	int sx=get<2>(e);
	int ny=sy+dy[nd];
	int nx=sx+dx[nd];
	if(ny<0||M<=ny||nx<1||N<nx||uc[sy][sx][ny][nx])continue;
	int nt=get<0>(e)+D+jam[sy][sx][ny][nx];
	if(k[ny][nx]&&nt%(2*k[ny][nx])<k[ny][nx]==nd%2)continue;
	s.insert(make_tuple(nt,ny,nx,nd));
      }
    }
  }
}
accuracy: 1
time_ms: 20
memory_kb: 6060
final_rank: 18

code_snippet: #include<iostream>
#include<vector>
#include<queue>
#include<tuple>
#include<functional>
#include<map>
#include<set>
using namespace std;

enum Direction {NORTH, EAST, SOUTH, WEST};
int dy[4] = {-1, 0, 1, 0};
int dx[4] = {0, 1, 0, -1};
enum {RED, BLUE};

class Point {
    int y_value, x_value;
public:
    Point() {}
    Point(int y, int x) :y_value(y), x_value(x) {
    }
    explicit Point(const string& s) {
        y_value = s[0] - 'a';
        x_value = 0;
        for(const auto& c: s.substr(2)) x_value = x_value * 10 + c - '0';
        --x_value;
    }
    int x() const {return x_value;}
    int y() const {return y_value;}
    bool operator<(const Point& p) const {return y() != p.y() ? y() < p.y() : x() < p.x();}
    bool operator>(const Point& p) const {return y() != p.y() ? y() > p.y() : x() > p.x();}
    bool operator==(const Point& p) const {return y() == p.y() && x() == p.x();}
};

class Vertex {
    Point point_value;
    int direction_value;
    int minute_value;
public:
    Vertex(const Point& p, int d, int m) :point_value(p), direction_value(d), minute_value(m) {}
    const Point point() const {return point_value;}
    int y() const {return point_value.y();}
    int x() const {return point_value.x();}
    int direction() const {return direction_value;}
    int minute() const {return minute_value;}
    void minute(int m) {minute_value = m;}
    bool operator<(const Vertex& v) const {
        if(minute() != v.minute()) return minute() < v.minute();
        if(direction() != v.direction()) return direction() < v.direction();
        return point() < v.point();
    }
    bool operator>(const Vertex& v) const {
        if(minute() != v.minute()) return minute() > v.minute();
        if(direction() != v.direction()) return direction() > v.direction();
        return point() > v.point();
    }
};

typedef tuple<Point, Point> Edge;

int M, N, D;
map<Point, int> signal;
set<Edge> construction;
map<Edge, int> jam;

int Dijkstra(const Point& start, const Point& goal) {
    set<Vertex> visited;
    priority_queue<Vertex, vector<Vertex>, greater<Vertex>> q;
    q.push(Vertex(start, EAST, 0));
    while(!q.empty()) {
        Vertex current = q.top();
        q.pop();
        if(current.point() == goal) return current.minute();
        if(visited.count(current)) continue;
        visited.insert(current);
        for(int d = 0; d < 4; ++d) {
            if(current.direction() == (d + 2) % 4) continue;
            Vertex next(Point(current.y() + dy[d], current.x() + dx[d]), d, current.minute());
            if(next.y() < 0 || M <= next.y() || next.x() < 0 || N <= next.x()) continue;
            Edge edge(Point(current.point()), Point(next.point()));
            if(construction.count(edge)) continue;
            int add = D;
            if(jam.count(edge)) add += jam[edge];
            next.minute(current.minute() + add);
            if(signal.count(next.point())) {
                int we = (next.minute() / signal[next.point()]) & 1;
                if((next.direction() == NORTH || next.direction() == SOUTH) && we == BLUE) continue;
                if((next.direction() == EAST || next.direction() == WEST) && we == RED) continue;
            }
            q.push(next);
        }
    }
    return -1;
}

int main() {
    while(cin >> M >> N, M | N) {
        int ns, nc, nj, k, d;
        string p, p1, p2;
        cin >> D;
        signal.clear();
        for(cin >> ns; ns > 0; --ns) {
            cin >> p >> k;
            signal[Point(p)] = k;
        }
        construction.clear();
        for(cin >> nc; nc > 0; --nc) {
            cin >> p1 >> p2;
            construction.insert(Edge(Point(p1), Point(p2)));
            construction.insert(Edge(Point(p2), Point(p1)));
        }
        jam.clear();
        for(cin >> nj; nj > 0; --nj) {
            cin >> p1 >> p2 >> d;
            jam[Edge(Point(p1), Point(p2))] = jam[Edge(Point(p2), Point(p1))] = d;
        }
        cin >> p1 >> p2;
        Point start(p1), goal(p2);

        cout << Dijkstra(start, goal) << endl;
    }
}
accuracy: 1
time_ms: 60
memory_kb: 5112
final_rank: 16

code_snippet: #include<iostream>
#include<queue>
#include<algorithm>
#include<sstream>
using namespace std;
int dx[4]={0,1,0,-1};
int dy[4]={-1,0,1,0};
int INF=(1<<24);
int c2i(char ch){return ch-'a';}
int str2i(string str){
  stringstream ss;
  int res;
  ss<<str;
  ss>>res;
  return res-1; 
}
 
int M,N,D,ns,nc,nj,Sy,Sx,Gy,Gx,lcm;
int t[20][20][4];
int k[20][20];
 
bool u[20][20][101][4];
bool vd[20][20][101][4];
 
void input();
void init();
void solve();
void dijkstra();
 
int main(){
  while(1){
    cin>>N>>M;
    if(M==0&&N==0)break;
    cin>>D;
    init();
    input();
    solve();
  }
  return 0;
}
 
void dijkstra(){
  int Y,X,Z,dir,ny,nx,nz;
  u[Sy][Sx][0][1]=true;
 
  while(1){
    Y=X=-1;
    for(int a=0;a<101;a++)
      for(int b=0;b<N;b++)
    for(int c=0;c<M;c++)
      for(int d=0;d<4;d++)
        if(u[b][c][a][d]&&!vd[b][c][a%lcm][d]&&Y==-1&&X==-1){Y=b;X=c;Z=a;dir=d;}
    if(Y==-1&&X==-1)break;
    vd[Y][X][Z%lcm][dir]=true;
    if(Y==Gy&&X==Gx)break;
    //cout<<Y<<' '<<X<<' '<<Z<<' '<<dir<<endl;
    if(k[Y][X]>0&&dir%2==1&&(Z/k[Y][X])%2==0)continue;
    if(k[Y][X]>0&&dir%2==0&&(Z/k[Y][X])%2==1)continue;
    for(int i=0;i<4;i++){ 
      ny=Y+dy[i];nx=X+dx[i];nz=Z+t[Y][X][i];
      if((dir+2)%4==i)continue;
      if(ny<0||ny>=N||nx<0||nx>=M||nz>100)continue;
      u[ny][nx][nz][i]=true;
      //if(ny==1&&nx==3)cout<<Y<<'-'<<X<<'-'<<Z<<'-'<<dir<<endl;
    }
     
     
  }//while
}
 
void solve(){
  dijkstra();
  for(int i=0;i<101;i++){
    for(int j=0;j<4;j++){
      if(!u[Gy][Gx][i][j])continue;
      cout<<i<<endl;
      return;
    }
  }
}
 
void input(){
  string str;
  int y,x,Y,X,d;
  lcm=1;
  cin>>ns;
  for(int i=0;i<ns;i++){
    cin>>str;
    y=c2i(str[0]);
    x=str2i(str.substr(2));
    cin>>k[y][x];
    lcm=lcm/__gcd(lcm,k[y][x])*k[y][x];
  }
  cin>>nc;
 
  for(int i=0;i<nc;i++){
    cin>>str;
    y=c2i(str[0]);
    x=str2i(str.substr(2));
    cin>>str;
    Y=c2i(str[0]);
    X=str2i(str.substr(2));
    for(int j=0;j<4;j++){
      if(y+dy[j]==Y&&x+dx[j]==X){
    t[y][x][j]=INF;
    t[Y][X][(j+2)%4]=INF;
    break;
      }
    }
  }
 
  cin>>nj;
  for(int i=0;i<nj;i++){
    cin>>str;
    y=c2i(str[0]);
    x=str2i(str.substr(2));
    cin>>str;
    Y=c2i(str[0]);
    X=str2i(str.substr(2));
    cin>>d;
    for(int j=0;j<4;j++){
      if(y+dy[j]==Y&&x+dx[j]==X){
    t[y][x][j]+=d;
    t[Y][X][(j+2)%4]+=d;
    break;
      }
    }
  }
   
  cin>>str;
  Sy=c2i(str[0]);
  Sx=str2i(str.substr(2));
  cin>>str;
  Gy=c2i(str[0]);
  Gx=str2i(str.substr(2));
 
}
 
void init(){
  for(int i=0;i<20;i++){
    for(int j=0;j<20;j++){
      for(int K=0;K<4;K++){
	t[i][j][K]=D;
      }
      k[i][j]=0;
      for(int K=0;K<101;K++){
	for(int l=0;l<4;l++){
	  u[i][j][K][l]=false;
	  vd[i][j][K][l]=false;
	}
      }
    }
  }
}
accuracy: 1
time_ms: 730
memory_kb: 1556
final_rank: 20

code_snippet: #define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f

#include <iostream>
#include <cstdio>
#include <sstream>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <limits>
#include <map>
#include <string>
#include <cstring>
#include <set>
#include <deque>
#include <bitset>
#include <list>
#include <cctype>
#include <utility>
  
using namespace std;
  
typedef long long ll;
typedef pair <int,int> P;
typedef pair <int,P> PP;
  
static const double EPS = 1e-8;
  
static const int tx[] = {0,1,0,-1};
static const int ty[] = {-1,0,1,0};

vector<string> split(const string &str, char delim){
  vector<string> res;
  size_t current = 0, found;
  while((found = str.find_first_of(delim, current)) != string::npos){
    res.push_back(string(str, current, found - current));
    current = found + 1;
  }
  res.push_back(string(str, current, str.size() - current));
  return res;
}

pair<char,int> conv(char point[32]){
  vector<string> v_pos = split(point,'-');
  string alpha = v_pos[0];
  string num = v_pos[1];
  return make_pair(alpha[0],atoi(num.c_str()));
}

bool dp[201][4][21][21];

int main(){
  int total_east2west_roads;
  int total_north2south_roads;
  while(~scanf("%d %d",
	       &total_east2west_roads,
	       &total_north2south_roads)){
    if(total_east2west_roads == 0 && total_north2south_roads == 0) continue;
    int normal_required_time;
    scanf("%d",&normal_required_time);

    int traffic_light[21][21];
    bool has_construction[21][21][21][21];
    int traffic_jam[21][21][21][21];
    memset(traffic_light,0,sizeof(traffic_light));
    memset(traffic_jam,0,sizeof(traffic_jam));
    memset(has_construction,false,sizeof(has_construction));

    int total_traffic_lights;
    scanf("%d",&total_traffic_lights);
    for(int traffic_light_idx = 0; traffic_light_idx < total_traffic_lights; traffic_light_idx++){
      char point[32];
      int period;
      scanf("%s %d",point,&period);
      pair<char,int> pos = conv(point);
      traffic_light[pos.first - 'a'][pos.second - 1] = period;
    }
    int total_roads_being_constructed;
    scanf("%d",&total_roads_being_constructed);
    for(int road_idx = 0; road_idx < total_roads_being_constructed; road_idx++){
      char from[32];
      char to[32];
      scanf("%s %s",from,to);
      pair<char,int> pos_from = conv(from);
      pair<char,int> pos_to = conv(to);

      has_construction[pos_from.first - 'a'][pos_from.second - 1][pos_to.first - 'a'][pos_to.second - 1] = true;
      has_construction[pos_to.first - 'a'][pos_to.second - 1][pos_from.first - 'a'][pos_from.second - 1] = true;
    }

    int total_traffic_jam_roads;
    scanf("%d",&total_traffic_jam_roads);
    for(int road_idx = 0; road_idx < total_traffic_jam_roads; road_idx++){
      char from[32];
      char to[32];
      int jam_required_time;     
      scanf("%s %s %d",from,to,&jam_required_time);
      pair<char,int> pos_from = conv(from);
      pair<char,int> pos_to = conv(to);
      traffic_jam[pos_from.first - 'a'][pos_from.second - 1][pos_to.first - 'a'][pos_to.second - 1] = jam_required_time;
      traffic_jam[pos_to.first - 'a'][pos_to.second - 1][pos_from.first - 'a'][pos_from.second - 1] = jam_required_time;
    }
    
    char start[32];
    char goal[32];

    scanf("%s %s",start,goal);
    pair<char,int> pos_s = conv(start);
    pair<char,int> pos_g = conv(goal);

    int sx = pos_s.second - 1;
    int sy = pos_s.first - 'a';

    int gx = pos_g.second - 1;
    int gy = pos_g.first - 'a';


    memset(dp,false,sizeof(dp));
    dp[0][1][sy][sx] = true;
    dp[0][0][sy][sx] = true;
    dp[0][2][sy][sx] = true;
    dp[0][3][sy][sx] = true;

    for(int time = 0;time <= 100; time++){
      for(int x=0;x<total_north2south_roads;x++){
	for(int y=0;y<total_east2west_roads;y++){
	  for(int next_dir=0;next_dir<4;next_dir++){

	    int dx = x + tx[next_dir];
	    int dy = y + ty[next_dir];
	    if(dx < 0 || dx >= total_north2south_roads
	       || dy < 0 || dy >= total_east2west_roads) continue;
	    if(has_construction[y][x][dy][dx]) continue;

	    for(int org_dir = 0; org_dir < 4 ; org_dir++){	    
	      if((org_dir+2)%4 == next_dir) continue;

	      if((org_dir == 1 || org_dir == 3) 
		 && traffic_light[y][x] != 0
		 && (time / traffic_light[y][x]) % 2 == 0) continue;
	      
	      if((org_dir == 0 || org_dir == 2) 
		 && traffic_light[y][x] != 0
		 && (time / traffic_light[y][x]) % 2 != 0) continue;

	      int jam = traffic_jam[y][x][dy][dx];
	      dp[time + jam + normal_required_time][next_dir][dy][dx]
		|= dp[time][org_dir][y][x];
	    }
	  }
	}
      }
    }
    int res = INF;
    for(int time = 0;time <= 100; time++){
      for(int dir = 0;dir < 4; dir++){
	if(dp[time][dir][gy][gx]){
	  res = min(time,res);
	}
      }
    }

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

  }
}
accuracy: 1
time_ms: 10
memory_kb: 2524
final_rank: 11

code_snippet: #include<iostream>
#include<queue>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
typedef pair < int , int > Pi;
typedef pair < int , Pi > Pii;
#define fr first
#define sc second

int M, N, D, ns, nc, nj;
char temp['z'+1],o;
int mas[20][20];
int go[20][20][20][20];
bool used[20][20][101];
Pi S, G;
int dy[] = { 0, 1, 0, -1}, dx[] = { -1, 0, 1, 0};

bool isover(int y, int x){
  return y < 0 || y >= M || x < 0 || x >= N;
}

bool isred(int y, int x, int time, bool istate){
  return ~mas[y][x] && !istate ^ time / mas[y][x] & 1;
}

int Dijkstra(){
  fill_n(**used, 20 * 20 * 101, false);
  priority_queue< Pii , vector< Pii > , greater< Pii > > que;
  que.push(Pii( 0, S)); //時間,座標
  while(!que.empty()){
    Pii p = que.top();
    que.pop();
    if(p.sc == G) return p.fr; //ごーるついた
    if(used[p.sc.fr][p.sc.sc][p.fr]++) continue;
    for(int i = 0 ; i < 4 ; i++ ){
      int ny = p.sc.fr + dy[i], nx = p.sc.sc + dx[i];
      if(isover(ny,nx)) continue; //そといった
      if(go[p.sc.fr][p.sc.sc][ny][nx] == -1) continue; //工事中
      int nexttime = p.fr + D + go[p.sc.fr][p.sc.sc][ny][nx];
      if(isred(ny, nx, nexttime, i & 1)) continue; //交差点に侵入不可
      que.push(Pii(nexttime, Pi( ny, nx)));
    }
  }
  return -1;
}


int main(){

  for(int i = 'a', j = 1 ; i <= 'z' ; i++, j++ ){ //まっぷてきなかんじ
    temp[i] = j;
  }


  while( cin >> M >> N, M){

    fill_n(*mas, 400, -1);
    fill_n(***go, 20 * 20 * 20 * 20, 0);

    cin >> D;
    cin >> ns;
    for(int i = 0 ; i < ns ; i++ ){
      char h;
      int v, k;
      cin >> h >> o >> v >> k;
      mas[temp[h] - 1][v - 1] = k;
    }

    cin >> nc;
    for(int i = 0 ; i < nc ; i++ ){
      char h1, h2;
      int v1, v2;
      cin >> h1 >> o >> v1 >> h2 >> o >> v2; //入力面倒くさいね
      go[temp[h1] - 1][v1 - 1][temp[h2] - 1][v2 - 1] = -1;
      go[temp[h2] - 1][v2 - 1][temp[h1] - 1][v1 - 1] = -1;
    }

    cin >> nj;
    for(int i = 0 ; i < nj ; i++ ){
      char h1, h2;
      int v1, v2, d;
      cin >> h1 >> o >> v1 >> h2 >> o >> v2 >> d;
      go[temp[h1] - 1][v1 - 1][temp[h2] - 1][v2 - 1] = d;
      go[temp[h2] - 1][v2 - 1][temp[h1] - 1][v1 - 1] = d;
    }

    char h1, h2;
    int v1, v2;
    cin >> h1 >> o >> v1 >> h2 >> o >> v2;
    S = Pi( temp[h1] - 1, v1 - 1);
    G = Pi( temp[h2] - 1, v2 - 1);

    cout << Dijkstra() << endl;
  }
}
accuracy: 1
time_ms: 10
memory_kb: 1888
final_rank: 8

code_snippet: #include<iostream>
#include<queue>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
typedef pair < int , int > Pi;
typedef pair < int , Pi > Pii;
#define fr first
#define sc second

int M, N, D, ns, nc, nj;
char temp['z'+1],o;
int mas[20][20];
int go[20][20][20][20];
bool used[20][20][101];
Pi S, G;
int dy[] = { 0, 1, 0, -1}, dx[] = { -1, 0, 1, 0};

bool isover(int y, int x){
  return y < 0 || y >= M || x < 0 || x >= N;
}

bool isred(int y, int x, int time, bool istate){
  if(mas[y][x] == -1) return false; //そもそも信号がない
  const int kankaku = mas[y][x];
  if(istate) return time / kankaku % 2;
  else return !(time / kankaku % 2);
}

int Dijkstra(){
  fill_n(**used, 20 * 20 * 101, false);
  priority_queue< Pii , vector< Pii > , greater< Pii > > que;
  que.push(Pii( 0, S)); //時間,座標
  while(!que.empty()){
    Pii p = que.top();
    que.pop();
    if(p.sc == G) return p.fr; //ごーるついた
    if(used[p.sc.fr][p.sc.sc][p.fr]++) continue;
    for(int i = 0 ; i < 4 ; i++ ){
      int ny = p.sc.fr + dy[i], nx = p.sc.sc + dx[i];
      if(isover(ny,nx)) continue; //そといった
      if(go[p.sc.fr][p.sc.sc][ny][nx] == -1) continue; //工事中
      int nexttime = p.fr + D + go[p.sc.fr][p.sc.sc][ny][nx];
      if(isred(ny, nx, nexttime, i % 2)) continue; //交差点に侵入不可
      que.push(Pii(nexttime, Pi( ny, nx)));
    }
  }
  return -1;
}


int main(){

  for(int i = 'a', j = 1 ; i <= 'z' ; i++, j++ ){ //まっぷてきなかんじ
    temp[i] = j;
  }


  while( cin >> M >> N, M){

    fill_n(*mas, 400, -1);
    fill_n(***go, 20 * 20 * 20 * 20, 0);

    cin >> D;
    cin >> ns;
    for(int i = 0 ; i < ns ; i++ ){
      char h;
      int v, k;
      cin >> h >> o >> v >> k;
      mas[temp[h] - 1][v - 1] = k;
    }

    cin >> nc;
    for(int i = 0 ; i < nc ; i++ ){
      char h1, h2;
      int v1, v2;
      cin >> h1 >> o >> v1 >> h2 >> o >> v2; //入力面倒くさいね
      go[temp[h1] - 1][v1 - 1][temp[h2] - 1][v2 - 1] = -1;
      go[temp[h2] - 1][v2 - 1][temp[h1] - 1][v1 - 1] = -1;
    }

    cin >> nj;
    for(int i = 0 ; i < nj ; i++ ){
      char h1, h2;
      int v1, v2, d;
      cin >> h1 >> o >> v1 >> h2 >> o >> v2 >> d;
      go[temp[h1] - 1][v1 - 1][temp[h2] - 1][v2 - 1] = d;
      go[temp[h2] - 1][v2 - 1][temp[h1] - 1][v1 - 1] = d;
    }

    char h1, h2;
    int v1, v2;
    cin >> h1 >> o >> v1 >> h2 >> o >> v2;
    S = Pi( temp[h1] - 1, v1 - 1);
    G = Pi( temp[h2] - 1, v2 - 1);

    cout << Dijkstra() << endl;
  }
}
accuracy: 1
time_ms: 10
memory_kb: 1888
final_rank: 8

code_snippet: #include <iostream>
#include <algorithm>
#include <string>
#include <sstream>
using namespace std;

const int MAXH = 21;
const int MAXW = 21;
const int MAXT = 103;
const int INF = 1<<28;
const int dx[] = {1,0,-1,0};
const int dy[] = {0,1,0,-1};
int H, W;
int D;
int G[MAXH][MAXW][4];
int S[MAXH][MAXW];
bool dp[MAXT][MAXH][MAXW][4];

pair<int,int> getPair() {
  string s;
  cin >> s;
  replace(s.begin(), s.end(), '-', ' ');
  stringstream ss(s);
  char h;
  int v;
  ss >> h >> v;
  return make_pair(h-'a', v-1);
}

int main() {
  while(cin >> H >> W && (H|W)) {
    cin >> D;
    {
      fill(S[0], S[MAXH], 0);
      int ns;
      cin >> ns;
      while(ns--) {
        pair<int,int> p = getPair();
        cin >> S[p.first][p.second];
      }
    }
    {
      fill(G[0][0], G[MAXH][0], D);
      int nc;
      cin >> nc;
      while(nc--) {
        pair<int,int> p1 = getPair();
        pair<int,int> p2 = getPair();
        int tx = p2.second - p1.second;
        int ty = p2.first - p1.first;
        for(int i = 0; i < 4; ++i) {
          if(dx[i] == tx && dy[i] == ty) {
            G[p1.first][p1.second][i] = INF;
            G[p2.first][p2.second][(i+2)%4] = INF;
            break;
          }
        }
      }
    }
    {
      int nj;
      cin >> nj;
      while(nj--) {
        pair<int,int> p1 = getPair();
        pair<int,int> p2 = getPair();
        int d;
        cin >> d;
        int tx = p2.second - p1.second;
        int ty = p2.first - p1.first;
        for(int i = 0; i < 4; ++i) {
          if(dx[i] == tx && dy[i] == ty) {
            G[p1.first][p1.second][i] = D+d;
            G[p2.first][p2.second][(i+2)%4] = D+d;
            break;
          }
        }
      }
    }
    pair<int,int> src = getPair();
    pair<int,int> dst = getPair();

    fill(dp[0][0][0], dp[MAXT][0][0], false);
    dp[0][src.first][src.second][0] = true;
    for(int t = 0; t < MAXT; ++t) {
      for(int i = 0; i < H; ++i) {
        for(int j = 0; j < W; ++j) {
          for(int d = 0; d < 4; ++d) {
            if(!dp[t][i][j][d]) continue;
            for(int k = 0; k < 4; ++k) {
              if(k == (d+2)%4) continue;
              if(G[i][j][k] == INF) continue;
              int ni = i + dy[k];
              int nj = j + dx[k];
              if(nj < 0 || nj >= W) continue;
              if(ni < 0 || ni >= H) continue;
              int nt = t + G[i][j][k];
              if(nt >= MAXT) continue;
              if(S[ni][nj]) {
                int a = (nt / S[ni][nj]) % 2;
                if(a == k % 2) continue;
              }
              dp[nt][ni][nj][k] = true;
            }
          }
        }
      }
    }

    try {
      for(int t = 0; t < MAXT; ++t) {
        for(int d = 0; d < 4; ++d) {
          if(dp[t][dst.first][dst.second][d]) {
            cout << t << endl;
            throw 0;
          }
        }
      }
    } catch(...) {}
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1472
final_rank: 5

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <cassert>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <algorithm>
#include <numeric>
#include <complex>
#include <stack>
#include <queue>
#include <list>
#include <set>
#include <map>
#include <bitset>
#include <functional>
#include <iterator>

using namespace std;

#define dump(n) cout<<"# "<<#n<<'='<<(n)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define peri(i,a,b) for(int i=int(b);i-->int(a);)
#define rep(i,n) repi(i,0,n)
#define per(i,n) peri(i,0,n)
#define iter(c) __typeof__((c).begin())
#define foreach(i,c) for(iter(c) i=(c).begin();i!=(c).end();++i)
#define all(c) (c).begin(),(c).end()
#define mp make_pair

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<vvvi> vvvvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;
typedef pair<int,int> pii;

const int INFTY=1<<29;
const double EPS=1e-9;

template<typename T1,typename T2>
ostream& operator<<(ostream& os,const pair<T1,T2>& p){
	return os<<'('<<p.first<<','<<p.second<<')';
}
template<typename T>
ostream& operator<<(ostream& os,const vector<T>& a){
	os<<'[';
	rep(i,a.size()) os<<(i?" ":"")<<a[i];
	return os<<']';
}

struct State{
	int i,j,t;
	int d; // {up,down,left,right}=>{0,1,2,3}
	State(){}
	State(int i,int j,int t,int d):i(i),j(j),t(t),d(d){}
	bool operator<(const State& s)const{return t<s.t;}
	bool operator>(const State& s)const{return t>s.t;}
};

int solve(const vvi& sig,const vvvvi& delay,pii start,pii goal)
{
	int h=sig.size(),w=sig[0].size();
	
	vvvvi vis(h,vvvi(w,vvi(4,vi(101))));
	priority_queue<State,vector<State>,greater<State>> pq;
	pq.emplace(start.first,start.second,0,3);
	while(!pq.empty()){
		State cur=pq.top(); pq.pop();
		if(vis[cur.i][cur.j][cur.d][cur.t])
			continue;
		vis[cur.i][cur.j][cur.d][cur.t]=1;
		if(cur.i==goal.first && cur.j==goal.second)
			break;
		
		int di[]={-1,1,0,0},dj[]={0,0,-1,1};
		rep(k,4) if(k!=(cur.d^1)){
			int ni=cur.i+di[k],nj=cur.j+dj[k];
			if(ni<0 || h<=ni || nj<0 || w<=nj)
				continue;
			int nt=cur.t+delay[cur.i][cur.j][ni][nj];
			if(nt>=INFTY)
				continue;
			if(sig[ni][nj]!=-1 && nt/sig[ni][nj]%2!=k/2)
				continue;
			pq.emplace(ni,nj,nt,k);
		}
	}
	const vvi& res=vis[goal.first][goal.second];
	rep(i,101) rep(j,4) if(res[j][i])
		return i;
}

int main()
{
	for(int h,w;scanf("%d%d",&h,&w),h|w;){
		int d,s; scanf("%d%d",&d,&s); // 基本コスト，信号機の数
		vvi sig(h,vi(w,-1));
		rep(i,s){
			char a; int b,t;
			scanf(" %c-%d %d",&a,&b,&t);
			sig[a-'a'][b-1]=t;
		}
		vvvvi delay(h,vvvi(w,vvi(h,vi(w,INFTY))));
		rep(i,h) rep(j,w) rep(k,h) rep(l,w){
			if(i==k && j==l)
				delay[i][j][k][l]=0;
			if(abs(i-k)+abs(j-l)==1)
				delay[i][j][k][l]=d;
		}
		// 工事中
		int c; scanf("%d",&c);
		rep(i,c){
			char a1,a2; int b1,b2;
			scanf(" %c-%d %c-%d",&a1,&b1,&a2,&b2);
			delay[a1-'a'][b1-1][a2-'a'][b2-1]=INFTY;
			delay[a2-'a'][b2-1][a1-'a'][b1-1]=INFTY;
		}
		// 渋滞
		int j; scanf("%d",&j);
		rep(i,j){
			char a1,a2; int b1,b2,dd;
			scanf(" %c-%d %c-%d %d",&a1,&b1,&a2,&b2,&dd);
			delay[a1-'a'][b1-1][a2-'a'][b2-1]+=dd;
			delay[a2-'a'][b2-1][a1-'a'][b1-1]+=dd;
		}
		// 始点・終点
		pii start,goal;{
			char a1,a2; int b1,b2;
			scanf(" %c-%d %c-%d",&a1,&b1,&a2,&b2);
			start=mp(a1-'a',b1-1);
			goal=mp(a2-'a',b2-1);
		}
		
		cout<<solve(sig,delay,start,goal)<<endl;
	}
	
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3028
final_rank: 14

code_snippet: #include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#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)

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

const int INF = 1001001001;

pii convert(const char* str)
{
	return pii(str[0]-'a', atoi(str+2)-1);
}

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

struct Data
{
	int y, x, d, t;
	Data(int y, int x, int d, int t) : y(y), x(x), d(d), t(t) {}
	bool operator< (const Data& d)const{
		return t > d.t;
	}
};

int main()
{
	int h, w;
	while(scanf("%d%d", &h, &w), h){
		int D, ns;
		scanf("%d%d", &D, &ns);

		int sign[20][20] = {{0}};
		rep(i, ns){
			char str[128];
			int k;
			scanf("%s%d", str, &k);
			pii p = convert(str);
			sign[p.first][p.second] = k;
		}

		bool work[20][20][4] = {{{false}}};
		int nc;
		scanf("%d", &nc);
		rep(i, nc){
			char str1[128], str2[128];
			scanf("%s%s", str1, str2);
			pii p1 = convert(str1), p2 = convert(str2);
			rep(j, 4){
				if(pii(p1.first+dy[j], p1.second+dx[j]) == p2){
					work[p1.first][p1.second][j] = true;
					work[p2.first][p2.second][(j+2)%2] = true;
					break;
				}
			}
		}

		int cost[20][20][4] = {{{0}}};
		int nj;
		scanf("%d", &nj);
		rep(i, nj){
			char str1[128], str2[128];
			int d;
			scanf("%s%s%d", str1, str2, &d);
			pii p1 = convert(str1), p2 = convert(str2);
			rep(j, 4){
				if(pii(p1.first+dy[j], p1.second+dx[j]) == p2){
					cost[p1.first][p1.second][j] = d;
					cost[p2.first][p2.second][(j+2)%2] = d;
					break;
				}
			}
		}

		char str1[128], str2[128];
		scanf("%s%s", str1, str2);
		pii start = convert(str1), goal = convert(str2);

		int ans = -1;
		bool visited[20][20][4][101] = {{{{false}}}};
		priority_queue<Data> Q;
		Q.push(Data(start.first, start.second, 3, 0));
		while(!Q.empty()){
			Data d = Q.top();
			Q.pop();
			if(visited[d.y][d.x][d.d][d.t])
				continue;
			visited[d.y][d.x][d.d][d.t] = true;
			if(d.y==goal.first && d.x==goal.second){
				ans = d.t;
				break;
			}
			rep(i, 4){
				if(abs(d.d-i) == 2 || work[d.y][d.x][i])
					continue;

				int py = d.y + dy[i];
				int px = d.x + dx[i];
				if(py<0 || h<=py || px<0 || w<=px)
					continue;

				int pt = d.t + D + cost[d.y][d.x][i];
				if(sign[py][px]==0 || (((pt/sign[py][px])%2) ^ (i%2==0))){
					Q.push(Data(py, px, i, pt));
				}
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1320
final_rank: 4

code_snippet: #include<stdio.h>
#include<map>
#include<queue>
#include<set>
#include<algorithm>
#include<string.h>


int arrows[4][3]={{0,1,3},
		  {0,1,2},
		  {1,2,3},
		  {0,2,3}};//右0、上1、左2、下3
int dxs[]={1,0,-1,0};
int dys[]={0,-1,0,1};



struct stop{
	//信号,周期はmapのvalに放り込む
	int x,y;
	bool operator<(const stop& s)const{
		if(x!=s.x)return x<s.x;
		return y<s.y;
	}
};
struct evePos{
	int r1,c1,r2,c2;
	//渋滞か工事中の表現
	bool operator<(const evePos& j)const{
		if(r1!=j.r1)return r1<j.r1;
		if(c1!=j.c1)return c1<j.c1;
		if(r2!=j.r2)return r2<j.r2;
		return c2<j.c2;
	}
};
struct car{
	int time,arrow;
	evePos pos;//手抜きをして構造体を流用、トラックが前にいたポジションと今のポジション
	bool operator<(const car& c)const{
		return time>c.time;//優先順位付きキュー用
	}
	car move(int nextArrow){
		car re;
		re.pos.r2=pos.r1;//今いるポジションを過去にする
		re.pos.c2=pos.c1;
		re.pos.r1=pos.r1+dys[nextArrow];
		re.pos.c1=pos.c1+dxs[nextArrow];
		re.time=time;
		re.arrow=nextArrow;
		return re;//タイム計算は後でする
	}
};

bool memo[101][21][21][4];//タイム、座標、向きで同じ状態を探索してないか

void calc(int h,int w){
	std::map<stop,int> stops;//信号
	std::priority_queue<car> pQ;
	std::set<evePos> stops2;//工事
	std::map<evePos,int> jams;//渋滞
	memset(memo,false,sizeof(memo));
	int d,ns,v1,v2,k,nc,nj;
	char h1,h2,t1;
	stop s1;
	
	scanf("%d %d",&d,&ns);
	for(int i=0;i<ns;i++){
		scanf("%c%c-%d %d",&t1,&h1,&v1,&k);
		s1.y=h1-'a';//0ベースで読み込み
		s1.x=v1-1;
		stops[s1]=k;
		//printf("<%c %d>",h1,v1);
	}
	scanf("%d",&nc);
	evePos e1;
	for(int i=0;i<nc;i++){
		scanf("%c%c-%d%c%c-%d",&t1,&h1,&v1,&t1,&h2,&v2);
		e1.r1=h1-'a';
		e1.c1=v1-1;
		e1.r2=h2-'a';
		e1.c2=v2-1;
		stops2.insert(e1);
		std::swap(e1.r1,e1.r2);//逆向きも登録する
		std::swap(e1.c1,e1.c2);
		stops2.insert(e1);
		//printf("<%c %d %c %d>",h1,v1,h2,v2);
	}
	scanf("%d",&nj);
	for(int i=0;i<nj;i++){
		scanf("%c%c-%d%c%c-%d %d",&t1,&h1,&v1,&t1,&h2,&v2,&k);
		e1.r1=h1-'a';
		e1.c1=v1-1;
		e1.r2=h2-'a';
		e1.c2=v2-1;
		jams[e1]=k;;
		std::swap(e1.r1,e1.r2);//逆向きも登録する
		std::swap(e1.c1,e1.c2);
		jams[e1]=k;
		//printf("<%c %d %c %d>",h1,v1,h2,v2);
	}
	car myCar,nextCar;
	myCar.time=myCar.arrow=0;
	int gx,gy;
	scanf("%c%c-%d%c%c-%d",&t1,&h1,&v1,&t1,&h2,&v2);
	gx=v2-1;
	gy=h2-'a';
	myCar.pos.r1=h1-'a';
	myCar.pos.c1=v1-1;//0ベース
	pQ.push(myCar);
	while(!pQ.empty()){
		myCar=pQ.top();
		pQ.pop();
		if(myCar.pos.r1==gy&&myCar.pos.c1==gx)break;//ゴールに到達
		//printf("<x=%d y=%d a=%d t=%d>",myCar.pos.c1,myCar.pos.r1,myCar.arrow,myCar.time);
		//scanf("%c",&t1);
		myCar.time+=d;
		for(int i=0;i<3;i++){
			nextCar=myCar.move(arrows[myCar.arrow][i]);
			s1.y=nextCar.pos.r1;//信号で止まらないかのチェック
			s1.x=nextCar.pos.c1;
			if(s1.x<0 || w<=s1.x || s1.y<0 || h<=s1.y)continue;//マップ外に飛び出した
			if(stops2.find(nextCar.pos)!=stops2.end())continue;//工事に引っかかった
			if(jams.find(nextCar.pos)!=jams.end()){
				nextCar.time+=jams[nextCar.pos];//渋滞に引っかかった
			}
			if(stops.find(s1)!=stops.end()){
				int t1=(nextCar.time/stops[s1])%2;//0なら東西停止、1なら南北停止
				int t2=nextCar.arrow%2;//東西なら0、1なら南北移動中
				if(t1==t2)continue;//信号に引っかかった
			}
			if(nextCar.time>100)continue;//100分以内という条件を満たしてない
			if(memo[nextCar.time][s1.x][s1.y][nextCar.arrow]==true)continue;//過去にこの状態を通った
			memo[nextCar.time][s1.x][s1.y][nextCar.arrow]=true;//この状態はもう終わってる
			pQ.push(nextCar);
		}
	}
	printf("%d\n",myCar.time);
}

int main(){
	int h,w;
	while(1){
		scanf("%d %d",&h,&w);
		if(h==0&&w==0)break;
		calc(h,w);
	}
}
accuracy: 1
time_ms: 10
memory_kb: 0
final_rank: 1

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
#include <functional>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
using namespace std;

typedef istringstream ISS;
typedef ostringstream OSS;
typedef vector<string> VS;
typedef int INT;
typedef vector<INT> VI;
typedef vector<VI> VVI;
typedef pair <INT, INT> II;
typedef vector <II> VII;

template<class T> ostream& operator << ( ostream& os, vector<T> v ) {
    for ( typename vector<T>::iterator it_i = v.begin(); it_i != v.end(); ++it_i ) {
        os << *it_i << ", ";
    }
    return os;
}


const int SIZE = 22;
const int NONE = -1;

int w, h;
int SG[SIZE][SIZE]; 
bool CS[SIZE][SIZE][SIZE][SIZE]; 
int D[SIZE][SIZE][SIZE][SIZE];
int sr, sc, gr, gc;

void init() {
    for ( int i = 0; i < SIZE; ++ i ) {
        for ( int j = 0; j < SIZE; ++ j ) {
            SG[i][j] = NONE;
        }
    }
    for ( int i1 = 0; i1 < SIZE; ++ i1 ) {
        for ( int j1 = 0; j1 < SIZE; ++ j1 ) {
            for ( int i2 = 0; i2 < SIZE; ++ i2 ) {
                for ( int j2 = 0; j2 < SIZE; ++ j2 ) {
                    CS[i1][j1][i2][j2] = false; 
                }
            }
        }
    }
}

II getPosition( string s ) {
    replace( s.begin(), s.end(), '-', ' ' );
    ISS iss( s );
    char H_;
    int H;
    int V;
    iss >> H_ >> V;
    H = H_ - 'a';
    V --;
    return II( H, V );
}

void input() {
    int D_;
    cin >> D_; 

    for ( int i1 = 0; i1 < SIZE; ++ i1 ) {
        for ( int j1 = 0; j1 < SIZE; ++ j1 ) {
            for ( int i2 = 0; i2 < SIZE; ++ i2 ) {
                for ( int j2 = 0; j2 < SIZE; ++ j2 ) {
                    D[i1][j1][i2][j2] = D_;
                }
            }
        }
    }

    int ns;
    cin >> ns;
    for ( int i = 0; i < ns; ++ i ) {
        string s;
        cin >> s;
        II ret1 = getPosition( s );
        int r = ret1.first, c = ret1.second;
        int k;
        cin >> k;
        SG[r][c] = k;
    }

    int nc;
    cin >> nc;
    for ( int i = 0; i < nc; ++ i ) {
        string s1, s2;
        cin >> s1 >> s2;
        II ret1 = getPosition( s1 ), ret2 = getPosition( s2 );
        int r1 = ret1.first, c1 = ret1.second, r2 = ret2.first, c2 = ret2.second;
        CS[r1][c1][r2][c2] = true;
        CS[r2][c2][r1][c1] = true;
    }

    int nj;
    cin >> nj;
    for ( int i = 0; i < nj; ++ i ) {
        string s1, s2;
        cin >> s1 >> s2;
        II ret1 = getPosition( s1 ), ret2 = getPosition( s2 );
        int r1 = ret1.first, c1 = ret1.second, r2 = ret2.first, c2 = ret2.second;
        int d;
        cin >> d;
        D[r1][c1][r2][c2] += d;
        D[r2][c2][r1][c1] += d;
    }

    {
        string s1, s2;
        cin >> s1 >> s2;
        II ret1 = getPosition( s1 ), ret2 = getPosition( s2 );
        int r1 = ret1.first, c1 = ret1.second, r2 = ret2.first, c2 = ret2.second;
        sr = r1, sc = c1, gr = r2, gc = c2;
    }
}

typedef pair <II, II> NODE; 
typedef priority_queue <NODE, vector<NODE>, greater<NODE> > QUEUE;

const int dr[4] = { 0, 1, 0, -1 };
const int dc[4] = { 1, 0, -1, 0 };

bool V[102][4][SIZE][SIZE];
void solveInit() {
    for ( int i1 = 0; i1 < 102; ++ i1 ) {
        for ( int j1 = 0; j1 < 4; ++ j1 ) {
            for ( int i2 = 0; i2 < SIZE; ++ i2 ) {
                for ( int j2 = 0; j2 < SIZE; ++ j2 ) {
                    V[i1][j1][i2][j2] = false;
                }
            }
        }
    }
}

bool isValidPos( int r, int c ) {
    return r >= 0 && r < h && c >= 0 && c < w;
}

int solve() {
    solveInit();

    QUEUE Q;
    Q.push( NODE( II( 0, 0 ), II( sr, sc ) ) );
    V[0][0][sr][sc] = true;

    while ( ! Q.empty() ) {
        NODE node = Q.top();
        Q.pop();

        int steps = node.first.first;
        int dir = node.first.second;
        int r = node.second.first;
        int c = node.second.second;

        if ( r == gr && c == gc ) {
            return steps;
        }
        

        for ( int i = 0; i < 4; ++ i ) {
            int ndir = i;
            if ( dir == ( ndir + 2 ) % 4 ) continue;
            int nr = r + dr[ndir];
            int nc = c + dc[ndir];
            if ( ! isValidPos( nr, nc ) ) continue;
            if ( CS[r][c][nr][nc] ) continue;
            int nsteps = steps + D[r][c][nr][nc];
            if ( nsteps > 100 ) continue;
            if ( SG[nr][nc] != NONE ) {
                int k = SG[nr][nc];
                bool f = ( ndir == 1 ) || ( ndir == 3 );
                if ( ( nsteps / k ) % 2 == 1 ) f = !f;
                if ( ! f ) continue;
            }
            if ( V[nsteps][ndir][nr][nc] ) continue;
            V[nsteps][ndir][nr][nc] = true;
            NODE next( II( nsteps, ndir ), II( nr, nc ) );
            Q.push( next );
        }

    }
    
    return -1;
}

int main() {
    while ( cin >> h >> w ) {
        if ( w == 0 && h == 0 ) break;
        init();
        input();
        cout << solve() << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 0
final_rank: 3

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
#include <functional>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
using namespace std;

typedef istringstream ISS;
typedef ostringstream OSS;
typedef vector<string> VS;
typedef int INT;
typedef vector<INT> VI;
typedef vector<VI> VVI;
typedef pair <INT, INT> II;
typedef vector <II> VII;

template<class T> ostream& operator << ( ostream& os, vector<T> v ) {
    for ( typename vector<T>::iterator it_i = v.begin(); it_i != v.end(); ++it_i ) {
        os << *it_i << ", ";
    }
    return os;
}


const int SIZE = 22;
const int NONE = -1;

int w, h;
int SG[SIZE][SIZE]; 
bool CS[SIZE][SIZE][SIZE][SIZE]; 
int D[SIZE][SIZE][SIZE][SIZE];
int sr, sc, gr, gc;

void init() {
    for ( int i = 0; i < SIZE; ++ i ) {
        for ( int j = 0; j < SIZE; ++ j ) {
            SG[i][j] = NONE;
        }
    }
    for ( int i1 = 0; i1 < SIZE; ++ i1 ) {
        for ( int j1 = 0; j1 < SIZE; ++ j1 ) {
            for ( int i2 = 0; i2 < SIZE; ++ i2 ) {
                for ( int j2 = 0; j2 < SIZE; ++ j2 ) {
                    CS[i1][j1][i2][j2] = false; 
                }
            }
        }
    }
}

II getPosition( string s ) {
    replace( s.begin(), s.end(), '-', ' ' );
    ISS iss( s );
    char H_;
    int H;
    int V;
    iss >> H_ >> V;
    H = H_ - 'a';
    V --;
    return II( H, V );
}

void input() {
    int D_;
    cin >> D_; 

    for ( int i1 = 0; i1 < SIZE; ++ i1 ) {
        for ( int j1 = 0; j1 < SIZE; ++ j1 ) {
            for ( int i2 = 0; i2 < SIZE; ++ i2 ) {
                for ( int j2 = 0; j2 < SIZE; ++ j2 ) {
                    D[i1][j1][i2][j2] = D_;
                }
            }
        }
    }

    int ns;
    cin >> ns;
    for ( int i = 0; i < ns; ++ i ) {
        string s;
        cin >> s;
        II ret1 = getPosition( s );
        int r = ret1.first, c = ret1.second;
        int k;
        cin >> k;
        SG[r][c] = k;
    }

    int nc;
    cin >> nc;
    for ( int i = 0; i < nc; ++ i ) {
        string s1, s2;
        cin >> s1 >> s2;
        II ret1 = getPosition( s1 ), ret2 = getPosition( s2 );
        int r1 = ret1.first, c1 = ret1.second, r2 = ret2.first, c2 = ret2.second;
        CS[r1][c1][r2][c2] = true;
        CS[r2][c2][r1][c1] = true;
    }

    int nj;
    cin >> nj;
    for ( int i = 0; i < nj; ++ i ) {
        string s1, s2;
        cin >> s1 >> s2;
        II ret1 = getPosition( s1 ), ret2 = getPosition( s2 );
        int r1 = ret1.first, c1 = ret1.second, r2 = ret2.first, c2 = ret2.second;
        int d;
        cin >> d;
        D[r1][c1][r2][c2] += d;
        D[r2][c2][r1][c1] += d;
    }

    {
        string s1, s2;
        cin >> s1 >> s2;
        II ret1 = getPosition( s1 ), ret2 = getPosition( s2 );
        int r1 = ret1.first, c1 = ret1.second, r2 = ret2.first, c2 = ret2.second;
        sr = r1, sc = c1, gr = r2, gc = c2;
    }
}

void debug() {
    for ( int i = 0; i < h; ++ i ) {
        for ( int j = 0; j < w; ++ j ) {
            if ( SG[i][j] != NONE )
                cout << "(" << i << "," << j << ")ツづ可信ツ債?機ツつェツつ?づゥ" << ", k = " << SG[i][j] << endl; 
        }
    }
    for ( int i1 = 0; i1 < h; ++ i1 ) {
        for ( int j1 = 0; j1 < w; ++ j1 ) {
            for ( int i2 = 0; i2 < h; ++ i2 ) {
                for ( int j2 = 0; j2 < w; ++ j2 ) {
                    cout << "(" << i1 << ", " << j1 << ")-(";
                    cout << i2 << ", " << j2 << ") = " << D[i1][j1][i2][j2] << endl;
                }
            }
        }
    }
    cout << "ツ始ツ点-ツ終ツ点" << ": (" << sr << ", " << sc << ") / (" << gr << ", " << gc << ")" << endl;
}

typedef pair <II, II> NODE; 
typedef priority_queue <NODE, vector<NODE>, greater<NODE> > QUEUE;

const int dr[4] = { 0, 1, 0, -1 };
const int dc[4] = { 1, 0, -1, 0 };

bool V[102][4][SIZE][SIZE];
void solveInit() {
    for ( int i1 = 0; i1 < 102; ++ i1 ) {
        for ( int j1 = 0; j1 < 4; ++ j1 ) {
            for ( int i2 = 0; i2 < SIZE; ++ i2 ) {
                for ( int j2 = 0; j2 < SIZE; ++ j2 ) {
                    V[i1][j1][i2][j2] = false;
                }
            }
        }
    }
}

bool isValidPos( int r, int c ) {
    return r >= 0 && r < h && c >= 0 && c < w;
}

int solve() {
    solveInit();

    QUEUE Q;
    Q.push( NODE( II( 0, 0 ), II( sr, sc ) ) );
    V[0][0][sr][sc] = true;

    while ( ! Q.empty() ) {
        NODE node = Q.top();
        Q.pop();

        int steps = node.first.first;
        int dir = node.first.second;
        int r = node.second.first;
        int c = node.second.second;

        if ( r == gr && c == gc ) {
            return steps;
        }
        

        for ( int i = 0; i < 4; ++ i ) {
            int ndir = i;
            if ( dir == ( ndir + 2 ) % 4 ) continue;
            int nr = r + dr[ndir];
            int nc = c + dc[ndir];
            if ( ! isValidPos( nr, nc ) ) continue;
            if ( CS[r][c][nr][nc] ) continue;
            int nsteps = steps + D[r][c][nr][nc];
            if ( nsteps > 100 ) continue;
            if ( SG[nr][nc] != NONE ) {
                int k = SG[nr][nc];
                bool f = ( ndir == 1 ) || ( ndir == 3 );
                if ( ( nsteps / k ) % 2 == 1 ) f = !f;
                if ( ! f ) continue;
            }
            if ( V[nsteps][ndir][nr][nc] ) continue;
            V[nsteps][ndir][nr][nc] = true;
            NODE next( II( nsteps, ndir ), II( nr, nc ) );
            Q.push( next );
        }

    }
    
    return -1;
}

int main() {
    while ( cin >> h >> w ) {
        if ( w == 0 && h == 0 ) break;
        init();
        input();
        cout << solve() << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 2328
final_rank: 10

code_snippet: #include<cstdio>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

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

struct edge{ int x1,y1,x2,y2,cost; };

int h,w,d;
int sig[20][20]; // 交差点 [y][x] にある信号の周期
int n_ban,n_jam;
edge ban[800],jam[800];
int sx,sy,gx,gy;

int solve(){
	static bool dp[101][20][20][4];
	rep(t,101) rep(i,h) rep(j,w) rep(k,4) dp[t][i][j][k]=false;
	dp[0][sy][sx][0]=true;
	rep(t,101) rep(i,h) rep(j,w) rep(k,4) {
		if(!dp[t][i][j][k]) continue;
		if(sig[i][j]!=0 && t/sig[i][j]%2==k%2) continue; // 信号が赤ならそこで打ち止め

		rep(k2,4) if((k-k2+4)%4!=2) { // k2 方向に進む
			int i2=i+dy[k2],j2=j+dx[k2];
			if(0<=i2 && i2<h && 0<=j2 && j2<w){
				// 道路が封鎖されていたらそこで打ち止め
				bool isban=false;
				rep(l,n_ban){
					if(ban[l].x1==j && ban[l].y1==i && ban[l].x2==j2 && ban[l].y2==i2
					|| ban[l].x2==j && ban[l].y2==i && ban[l].x1==j2 && ban[l].y1==i2) isban=true;
				}
				if(isban) continue;

				int t_jam=0;
				rep(l,n_jam){
					if(jam[l].x1==j && jam[l].y1==i && jam[l].x2==j2 && jam[l].y2==i2
					|| jam[l].x2==j && jam[l].y2==i && jam[l].x1==j2 && jam[l].y1==i2) t_jam=jam[l].cost;
				}

				int t2=t+d+t_jam;
				if(t2<=100){
					dp[t2][i2][j2][k2]=true;
				}
			}
		}
	}

	rep(t,101) rep(k,4) if(dp[t][gy][gx][k]) return t;
	return -1;
}

int main(){
	char a;
	int b;
	for(;scanf("%d%d%d",&h,&w,&d),h;){
		rep(i,h) rep(j,w) sig[i][j]=0; // 0 なら信号がない

		int n_sig; scanf("%d",&n_sig);
		rep(i,n_sig){
			int t;
			scanf(" %c%*c%d%d",&a,&b,&t);
			sig[a-'a'][b-1]=t;
		}

		scanf("%d",&n_ban);
		rep(i,n_ban){
			scanf(" %c%*c%d",&a,&b);
			ban[i].x1=b-1;
			ban[i].y1=a-'a';
			scanf(" %c%*c%d",&a,&b);
			ban[i].x2=b-1;
			ban[i].y2=a-'a';
		}

		scanf("%d",&n_jam);
		rep(i,n_jam){
			int t;
			scanf(" %c%*c%d",&a,&b);
			jam[i].x1=b-1;
			jam[i].y1=a-'a';
			scanf(" %c%*c%d%d",&a,&b,&t);
			jam[i].x2=b-1;
			jam[i].y2=a-'a';
			jam[i].cost=t;
		}

		{
			scanf(" %c%*c%d",&a,&b);
			sx=b-1;
			sy=a-'a';
			scanf(" %c%*c%d",&a,&b);
			gx=b-1;
			gy=a-'a';
		}

		printf("%d\n",solve());
	}

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