Problem:
Problem D: 伝説の剣
※ この問題には厨二成分が多く含まれます。胸焼けにご注意ください。
ついに復活を遂げた魔王は、再び世界を闇に包むために人間界に攻め入ろうとしていた。
魔王は、本格的な侵攻を始める前に、まず伝説の剣を破壊することにした。
前回の戦争において、魔王は伝説の剣を持つ勇者によって倒された。
魔王の体は闇の衣によって守られているため、生半可な攻撃では魔王を傷つけることはできない。
しかし、伝説の剣は、神々の加護により、魔王の闇の衣すら容易に貫いてしまう。
そのため、今回の戦争に勝利するためには、なんとしてもその伝説の剣を手に入れて破壊する必要がある。
調査の末、伝説の剣はとある遺跡の最奥に安置され、次代の勇者が現われるのを待っていることがわかった。
伝説の剣は、邪悪な者や盗賊によって奪われるのを防ぐために、周囲に点在する無数の宝珠によって封印されている。
魔王は、強力な魔力を持っているため、触れるだけで宝珠を破壊することができる。
ただし、宝珠による封印は多重構造になっており、表層から順に破壊していく必要がある。
例えば、第1の封印の宝珠を破壊する前に第2以降の封印の宝珠に触れたとしても、破壊することはできない。
また、複数の宝珠が同じ封印を構成していることもあるが、魔王はそのうちの一つに触れるだけで、同時にその封印を破壊することができる。
遺跡には神聖な力が満ちており、並の魔物では入ることすらままならない。
そこで、魔王自ら赴き伝説の剣を回収してくることになった。
いかに魔王といえど、長時間その力を受け続ければただではすまない。
魔王の右腕であるあなたの仕事は、念のため魔王が全ての封印を破壊し、伝説の剣の下に辿りつくまでの時間を求めることである。
Input
入力は、複数のデータセットからなり、入力の終わりはスペースで区切られたゼロ二つからなる行である。
データセットの総数は50以下である。
各データセットは、次の形式をしている。
w
h
s(1,1)
...
s(1,w)
s(2,1)
...
s(2,w)
...
s(h,1)
...
s(h,w)
w
と
h
は、それぞれ遺跡のフロアを表現する行列データの幅と高さを示す整数であり、それぞれ
1 ≤ w, h ≤ 100
であり、
2 ≤ w + h ≤ 100
と仮定して良い。
続く
h
行はそれぞれ、スペースで区切られた
w
個の文字から構成されており、文字
s(y,x)
は、座標
(y,x)
の地点の状態を示す。
その意味は、以下の通りである。
S：魔王が最初にいる地点。フロアに必ず1つだけ存在する。
G：伝説の剣の地点。必ず1つだけ存在する。
.：なにもない。
数字：宝珠がある地点。数字は構成する封印の番号を示す。数字は1以上の整数であり、間の数字に抜けはないとしてよい。
また、魔王は、遺跡のフロア内の上下左右の隣接する座標に移動することができ、その移動にかかる時間を1とする。
破壊できる宝珠は触れるだけで破壊できるため、宝珠の破壊には時間はかからない。
Output
各データセットに対して、魔王が全ての封印を破壊し、伝説に剣に辿りつくために必要な最短時間を出力せよ。
Sample Input
10 10
S . . . . . . . . .
. . . . . . . . . .
. . . . 1 . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . 3 . .
. . . . . . . . . .
. . . . . 4 . . . .
. . . . . . . . . .
2 . . . . . . . . G
10 10
S . . . . . 3 . . .
. . 3 . . . . . . .
. . . . 1 . . . . .
. . . . . . 4 . . .
. . 3 . . . 1 . . .
. . . . . . . 3 . .
. . . . . . . . . .
. . . . . 4 . . . .
. . . . . 5 . . . .
2 . . . . . . . . G
10 10
S . . . . . . . . 1
. . . . . 5 . . . .
. 4 . . . . . . . .
. . . . 8 . 9 . . .
. . . . 10 . . . . .
. . 7 . G . . . . .
. . . 11 . . . . . .
3 . . . . . . . . 6
. . . . . . . 2 . .
. . . . . . . . . .
0 0
Output for Sample Input
38
36
71

Submitted solutions:

code_snippet: #include <algorithm>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <vector>
using namespace std;
#define fr first
#define sc second
typedef pair<int, int> P;
P s, g;
typedef pair<P, P> Q;
int h, w, sx, sy, gx, gy, c, dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0},
                             num[105][105];
bool used[2500][105][105];
char wara[100];
int bfs();
int main() {
  while (cin >> w >> h && w || h) {
    memset(num, 0, sizeof(num));
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cin >> wara;
        if (strcmp(wara, "S") == 0)
          s = P(i, j);
        else if (strcmp(wara, "G") == 0)
          g = P(i, j);
        else if (strcmp(wara, ".") != 0) {
          c = max(c, atoi(wara));
          num[i][j] = atoi(wara);
        }
      }
    }
    num[g.fr][g.sc] = c + 1;
    cout << bfs() << endl;
    c = 0;
  }
}
int bfs() {
  memset(used, false, sizeof(used));
  queue<Q> que;
  que.push(Q(s, P(1, 0)));
  used[1][s.fr][s.sc] = true;
  while (!que.empty()) {
    Q q = que.front();
    que.pop();
    if (q.sc.fr == c + 1 && q.fr == g)
      return q.sc.sc;
    if (num[q.fr.fr][q.fr.sc] == q.sc.fr &&
        !used[q.sc.fr + 1][q.fr.fr][q.fr.sc]) {
      used[q.sc.fr + 1][q.fr.fr][q.fr.sc] = true;
      q.sc.fr++;
    }
    for (int i = 0; i < 4; i++) {
      int nx = q.fr.fr + dx[i], ny = q.fr.sc + dy[i];
      bool flg = true;
      if (nx >= 0 && nx < h && ny >= 0 && ny < w && !used[q.sc.fr][nx][ny]) {
        used[q.sc.fr][nx][ny] = true;
        que.push(Q(P(nx, ny), P(q.sc.fr + (flg ? 0 : 1), q.sc.sc + 1)));
      }
    }
  }
  return -1;
}
accuracy: 1
time_ms: 210
memory_kb: 30108
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> Pi;
typedef pair<Pi, int> Pii;
#define dp second
const int INF = 1 << 30;
int dist(Pi a, Pi b) {
  return abs(a.first - b.first) + abs(a.second - b.second);
}
int main() {
  int w, h;
  Pi goal;
  while (cin >> w >> h, w) {
    vector<Pii> num[2500];
    int size = 0, hoge;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        string str;
        cin >> str;
        if (str != ".") {
          if (str == "S")
            num[0].push_back(Pii(Pi(i, j), 0));
          else if (str == "G")
            goal = Pi(i, j);
          else {
            num[hoge = atoi(str.c_str())].push_back(Pii(Pi(i, j), INF));
            size = max(hoge, size);
          }
        }
      }
    }
    num[++size].push_back(Pii(goal, INF));
    for (int idx = 1; idx <= size; idx++) {
      for (int i = num[idx].size() - 1; i >= 0; i--) {
        for (int j = num[idx - 1].size() - 1; j >= 0; j--) {
          num[idx][i].dp = min(num[idx][i].dp,
                               num[idx - 1][j].dp + dist(num[idx - 1][j].first,
                                                         num[idx][i].first));
        }
      }
    }
    cout << num[size][0].dp << endl;
  }
  return (0);
}
accuracy: 1
time_ms: 10
memory_kb: 3316
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, n) for (int i = a; i < n; i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(v) (v).begin(), (v).end()
typedef long long int64;
const static int INF = 1 << 28;
typedef pair<int, int> Pi;
typedef pair<int, Pi> Pii;
int main() {
  int w, h;
  while (cin >> w >> h, w) {
    vector<Pii> mas[2501];
    Pi goal;
    int count = 0;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        string line;
        cin >> line;
        if (isdigit(line[0])) {
          mas[atoi(line.c_str())].push_back(Pii(INF, Pi(i, j)));
          count = max(count, atoi(line.c_str()));
        } else if (line[0] == 'S') {
          mas[0].push_back(Pii(0, Pi(i, j)));
        } else if (line[0] == 'G') {
          goal = Pi(i, j);
        }
      }
    }
    mas[count + 1].push_back(Pii(INF, goal));
    for (int i = 1; !mas[i].empty(); i++) {
      for (int j = 0; j < mas[i].size(); j++) {
        for (int k = 0; k < mas[i - 1].size(); k++) {
          mas[i][j].first = min(
              mas[i][j].first,
              mas[i - 1][k].first +
                  abs(mas[i - 1][k].second.first - mas[i][j].second.first) +
                  abs(mas[i - 1][k].second.second - mas[i][j].second.second));
        }
      }
    }
    cout << mas[count + 1][0].first << endl;
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3188
final_rank: 1

code_snippet: #line 2 "/home/yuruhiya/programming/library/template/template_no_Ruby.cpp"
#include <bits/stdc++.h>
#line 4 "/home/yuruhiya/programming/library/template/constants.cpp"
#include <string_view>
#line 7 "/home/yuruhiya/programming/library/template/constants.cpp"

#define rep(i, n) for (int i = 0; i < (n); ++i)
#define FOR(i, m, n) for (int i = (m); i < (n); ++i)
#define rrep(i, n) for (int i = (n)-1; i >= 0; --i)
#define rfor(i, m, n) for (int i = (m); i >= (n); --i)
#define unless(c) if (!(c))
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define range_it(a, l, r) (a).begin() + (l), (a).begin() + (r)

using namespace std;
using ll = long long;
using LD = long double;
using VB = vector<bool>;
using VVB = vector<VB>;
using VI = vector<int>;
using VVI = vector<VI>;
using VL = vector<ll>;
using VVL = vector<VL>;
using VS = vector<string>;
using VD = vector<LD>;
using PII = pair<int, int>;
using VP = vector<PII>;
using PLL = pair<ll, ll>;
using VPL = vector<PLL>;
template <class T> using PQ = priority_queue<T>;
template <class T> using PQS = priority_queue<T, vector<T>, greater<T>>;
constexpr int inf = 1000000000;
constexpr long long inf_ll = 1000000000000000000ll, MOD = 1000000007;
constexpr long double PI = 3.14159265358979323846, EPS = 1e-12;
namespace CharacterClass {
	constexpr string_view
	    digit = "0123456789",
	    xdigit = "0123456789ABCDEFabcdef", lower = "abcdefghijklmnopqrstuvwxyz",
	    upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
	    alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
	    alnum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
	    word = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz",
	    punct = R"(!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)",
	    graph =
	        R"(!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~)",
	    print =
	        R"( !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~)",
	    blank = " \t", space = " \t\n\r\f\v";
}  // namespace CharacterClass
#line 7 "/home/yuruhiya/programming/library/template/Input.cpp"
using namespace std;

#ifdef _WIN32
#define getchar_unlocked _getchar_nolock
#define putchar_unlocked _putchar_nolock
#define fwrite_unlocked fwrite
#define fflush_unlocked fflush
#endif
class Scanner {
	static int gc() {
		return getchar_unlocked();
	}
	static char next_char() {
		char c;
		read(c);
		return c;
	}
	template <class T> static void read(T& v) {
		cin >> v;
	}
	static void read(char& v) {
		while (isspace(v = gc()))
			;
	}
	static void read(bool& v) {
		v = next_char() != '0';
	}
	static void read(string& v) {
		v.clear();
		for (char c = next_char(); !isspace(c); c = gc()) v += c;
	}
	static void read(int& v) {
		v = 0;
		bool neg = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c); c = gc()) v = v * 10 + (c - '0');
		if (neg) v = -v;
	}
	static void read(long long& v) {
		v = 0;
		bool neg = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c); c = gc()) v = v * 10 + (c - '0');
		if (neg) v = -v;
	}
	static void read(double& v) {
		v = 0;
		double dp = 1;
		bool neg = false, after_dp = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c) || c == '.'; c = gc()) {
			if (c == '.') {
				after_dp = true;
			} else if (after_dp) {
				v += (c - '0') * (dp *= 0.1);
			} else {
				v = v * 10 + (c - '0');
			}
		}
		if (neg) v = -v;
	}
	static void read(long double& v) {
		v = 0;
		long double dp = 1;
		bool neg = false, after_dp = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c) || c == '.'; c = gc()) {
			if (c == '.') {
				after_dp = true;
			} else if (after_dp) {
				v += (c - '0') * (dp *= 0.1);
			} else {
				v = v * 10 + (c - '0');
			}
		}
		if (neg) v = -v;
	}
	template <class T, class U> static void read(pair<T, U>& v) {
		read(v.first);
		read(v.second);
	}
	template <class T> static void read(vector<T>& v) {
		for (auto& e : v) read(e);
	}
	template <size_t N = 0, class T> static void read_tuple_impl(T& v) {
		if constexpr (N < tuple_size_v<T>) {
			read(get<N>(v));
			read_tuple_impl<N + 1>(v);
		}
	}
	template <class... T> static void read(tuple<T...>& v) {
		read_tuple_impl(v);
	}
	struct ReadVectorHelper {
		size_t n;
		ReadVectorHelper(size_t _n) : n(_n) {}
		template <class T> operator vector<T>() {
			vector<T> v(n);
			read(v);
			return v;
		}
	};
	struct Read2DVectorHelper {
		size_t n, m;
		Read2DVectorHelper(const pair<size_t, size_t>& nm) : n(nm.first), m(nm.second) {}
		template <class T> operator vector<vector<T>>() {
			vector<vector<T>> v(n, vector<T>(m));
			read(v);
			return v;
		}
	};

public:
	string read_line() const {
		string v;
		for (char c = gc(); c != '\n' && c != '\0'; c = gc()) v += c;
		return v;
	}
	template <class T> T read() const {
		T v;
		read(v);
		return v;
	}
	template <class T> vector<T> read_vector(size_t n) const {
		vector<T> a(n);
		read(a);
		return a;
	}
	template <class T> operator T() const {
		return read<T>();
	}
	int operator--(int) const {
		return read<int>() - 1;
	}
	ReadVectorHelper operator[](size_t n) const {
		return ReadVectorHelper(n);
	}
	Read2DVectorHelper operator[](const pair<size_t, size_t>& nm) const {
		return Read2DVectorHelper(nm);
	}
	void operator()() const {}
	template <class H, class... T> void operator()(H&& h, T&&... t) const {
		read(h);
		operator()(forward<T>(t)...);
	}

private:
	template <template <class...> class, class...> struct Multiple;
	template <template <class...> class V, class Head, class... Tail>
	struct Multiple<V, Head, Tail...> {
		template <class... Args> using vec = V<vector<Head>, Args...>;
		using type = typename Multiple<vec, Tail...>::type;
	};
	template <template <class...> class V> struct Multiple<V> { using type = V<>; };
	template <class... T> using multiple_t = typename Multiple<tuple, T...>::type;
	template <size_t N = 0, class T> void multiple_impl(T& t) const {
		if constexpr (N < tuple_size_v<T>) {
			auto& vec = get<N>(t);
			using V = typename remove_reference_t<decltype(vec)>::value_type;
			vec.push_back(read<V>());
			multiple_impl<N + 1>(t);
		}
	}

public:
	template <class... T> auto multiple(size_t h) const {
		multiple_t<T...> result;
		while (h--) multiple_impl(result);
		return result;
	}
} in;
#define inputs(T, ...) \
	T __VA_ARGS__;     \
	in(__VA_ARGS__)
#define ini(...) inputs(int, __VA_ARGS__)
#define inl(...) inputs(long long, __VA_ARGS__)
#define ins(...) inputs(string, __VA_ARGS__)
#line 7 "/home/yuruhiya/programming/library/template/Output.cpp"
#include <charconv>
#line 10 "/home/yuruhiya/programming/library/template/Output.cpp"
using namespace std;

struct BoolStr {
	const char *t, *f;
	BoolStr(const char* _t, const char* _f) : t(_t), f(_f) {}
} Yes("Yes", "No"), yes("yes", "no"), YES("YES", "NO"), Int("1", "0");
struct DivStr {
	const char *d, *l;
	DivStr(const char* _d, const char* _l) : d(_d), l(_l) {}
} spc(" ", "\n"), no_spc("", "\n"), end_line("\n", "\n"), comma(",", "\n"),
    no_endl(" ", "");
class Output {
	BoolStr B{Yes};
	DivStr D{spc};

public:
	void put(int v) const {
		char buf[12]{};
		if (auto [ptr, e] = to_chars(begin(buf), end(buf), v); e == errc{}) {
			fwrite(buf, sizeof(char), ptr - buf, stdout);
		} else {
			assert(false);
		}
	}
	void put(long long v) const {
		char buf[21]{};
		if (auto [ptr, e] = to_chars(begin(buf), end(buf), v); e == errc{}) {
			fwrite(buf, sizeof(char), ptr - buf, stdout);
		} else {
			assert(false);
		}
	}
	void put(bool v) const {
		put(v ? B.t : B.f);
	}
	void put(vector<bool>::reference v) const {
		put(v ? B.t : B.f);
	}
	void put(char v) const {
		putchar_unlocked(v);
	}
	void put(const char* v) const {
		fwrite_unlocked(v, 1, strlen(v), stdout);
	}
	void put(double v) const {
		printf("%.20f", v);
	}
	void put(long double v) const {
		printf("%.20Lf", v);
	}
	template <class T> void put(const T& v) const {
		cout << v;
	}
	template <class T, class U> void put(const pair<T, U>& v) const {
		put(v.first);
		put(D.d);
		put(v.second);
	}
	template <class InputIterater>
	void put_range(const InputIterater& begin, const InputIterater& end) const {
		for (InputIterater i = begin; i != end; ++i) {
			if (i != begin) put(D.d);
			put(*i);
		}
	}
	template <class T> void put(const vector<T>& v) const {
		put_range(v.begin(), v.end());
	}
	template <class T, size_t N> void put(const array<T, N>& v) const {
		put_range(v.begin(), v.end());
	}
	template <class T> void put(const vector<vector<T>>& v) const {
		for (size_t i = 0; i < v.size(); ++i) {
			if (i) put(D.l);
			put(v[i]);
		}
	}

	Output() = default;
	Output(const BoolStr& _boolstr, const DivStr& _divstr) : B(_boolstr), D(_divstr) {}
	Output& operator()() {
		put(D.l);
		return *this;
	}
	template <class H> Output& operator()(H&& h) {
		put(h);
		put(D.l);
		return *this;
	}
	template <class H, class... T> Output& operator()(H&& h, T&&... t) {
		put(h);
		put(D.d);
		return operator()(forward<T>(t)...);
	}
	template <class InputIterator>
	Output& range(const InputIterator& begin, const InputIterator& end) {
		put_range(begin, end);
		put(D.l);
		return *this;
	}
	template <class T> Output& range(const T& a) {
		range(a.begin(), a.end());
		return *this;
	}
	template <class... T> void exit(T&&... t) {
		operator()(forward<T>(t)...);
		std::exit(EXIT_SUCCESS);
	}
	Output& flush() {
		fflush_unlocked(stdout);
		return *this;
	}
	Output& set(const BoolStr& b) {
		B = b;
		return *this;
	}
	Output& set(const DivStr& d) {
		D = d;
		return *this;
	}
	Output& set(const char* t, const char* f) {
		B = BoolStr(t, f);
		return *this;
	}
} out;
#line 6 "/home/yuruhiya/programming/library/template/functions.cpp"
using namespace std;

template <class T> int sz(const T& v) {
	return v.size();
}
template <class T, class U> int lower_index(const T& a, const U& v) {
	return lower_bound(all(a), v) - a.begin();
}
template <class T, class U> int upper_index(const T& a, const U& v) {
	return upper_bound(all(a), v) - a.begin();
}
template <class T> auto Slice(const T& v, size_t i, size_t len) {
	return i < v.size() ? T(v.begin() + i, v.begin() + min(i + len, v.size())) : T();
}
template <class T> T div_ceil(T n, T m) {
	return (n + m - 1) / m;
}
template <class T> T div_ceil2(T n, T m) {
	return div_ceil(n, m) * m;
}
template <class T> T triangle(T n) {
	return (n & 1) ? (n + 1) / 2 * n : n / 2 * (n + 1);
}
template <class T> T nC2(T n) {
	return (n & 1) ? (n - 1) / 2 * n : n / 2 * (n - 1);
}
template <class T> T middle(const T& l, const T& r) {
	return l + (r - l) / 2;
}
template <class T> bool chmax(T& a, const T& b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}
template <class T> bool chmin(T& a, const T& b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T> bool in_range(const T& v, const T& min, const T& max) {
	return min <= v && v < max;
}
template <class T> bool in_square(T n) {
	T s = sqrt(n);
	return s * s == n || (s + 1) * (s + 1) == n;
}
template <class T = long long> T BIT(int b) {
	return T(1) << b;
}
template <class T, class U = typename T::value_type> U Gcdv(const T& v) {
	return accumulate(next(v.begin()), v.end(), U(*v.begin()), gcd<U, U>);
}
template <class T, class U = typename T::value_type> U Lcmv(const T& v) {
	return accumulate(next(v.begin()), v.end(), U(*v.begin()), lcm<U, U>);
}
template <class T, class U> T Pow(T a, U n) {
	T result = 1;
	while (n > 0) {
		if (n & 1) {
			result *= a;
			n--;
		} else {
			a *= a;
			n >>= 1;
		}
	}
	return result;
}
template <class T, class U> T Powmod(T a, U n, T mod) {
	T result = 1;
	while (n > 0) {
		if (n & 1) {
			result = result * a % mod;
			n--;
		} else {
			a = a * a % mod;
			n >>= 1;
		}
	}
	return result;
}
namespace internal {
	template <class T, size_t N> auto make_vector(vector<int>& sizes, const T& init) {
		if constexpr (N == 1) {
			return vector(sizes[0], init);
		} else {
			int size = sizes[N - 1];
			sizes.pop_back();
			return vector(size, make_vector<T, N - 1>(sizes, init));
		}
	}
}  // namespace internal
template <class T, size_t N>
auto make_vector(const int (&sizes)[N], const T& init = T()) {
	vector s(rbegin(sizes), rend(sizes));
	return internal::make_vector<T, N>(s, init);
}
#line 7 "/home/yuruhiya/programming/library/template/template_no_Ruby.cpp"
#if __has_include(<library/dump.hpp>)
#include <library/dump.hpp>
#define LOCAL
#else
#define dump(...) ((void)0)
#endif

template <class T> constexpr T oj_local(const T& oj, const T& local) {
#ifndef LOCAL
	return oj;
#else
	return local;
#endif
}
#line 5 "/home/yuruhiya/programming/library/Utility/Point.cpp"
#include <optional>
#line 9 "/home/yuruhiya/programming/library/Utility/Point.cpp"
using namespace std;

struct Point {
	static int H, W;
	static const vector<Point> direction;
	using direction_iterator = vector<Point>::const_iterator;
	static void set_range(int _H, int _W) {
		H = _H;
		W = _W;
	}
	static constexpr Point zero() {
		return {0, 0};
	}
	static constexpr Point one() {
		return {1, 1};
	}
	static constexpr Point L() {
		return {-1, 0};
	}
	static constexpr Point R() {
		return {1, 0};
	}
	static constexpr Point U() {
		return {0, -1};
	}
	static constexpr Point D() {
		return {0, 1};
	}
	static constexpr Point LU() {
		return {-1, -1};
	}
	static constexpr Point LD() {
		return {-1, 1};
	}
	static constexpr Point RU() {
		return {1, -1};
	}
	static constexpr Point RD() {
		return {1, 1};
	}

	int x, y;
	constexpr Point() : x(0), y(0) {}
	constexpr Point(int _x, int _y) : x(_x), y(_y) {}
	constexpr Point(const pair<int, int>& xy) : x(xy.first), y(xy.second) {}
	Point(int n) : x(n % W), y(n / W) {}
	constexpr Point operator+() const {
		return *this;
	}
	constexpr Point operator-() const {
		return {-x, -y};
	}
	constexpr Point operator+(const Point& p) const {
		return Point(*this) += p;
	}
	constexpr Point operator-(const Point& p) const {
		return Point(*this) -= p;
	}
	constexpr Point operator*(const Point& p) const {
		return Point(*this) *= p;
	}
	constexpr Point operator/(const Point& p) const {
		return Point(*this) /= p;
	}
	constexpr Point operator%(const Point& p) const {
		return Point(*this) %= p;
	}
	constexpr Point operator+(int n) const {
		return Point(*this) += n;
	}
	constexpr Point operator-(int n) const {
		return Point(*this) -= n;
	}
	constexpr Point operator*(int n) const {
		return Point(*this) *= n;
	}
	constexpr Point operator/(int n) const {
		return Point(*this) /= n;
	}
	constexpr Point operator%(int n) const {
		return Point(*this) %= n;
	}
	constexpr Point& operator+=(const Point& p) {
		x += p.x;
		y += p.y;
		return *this;
	}
	constexpr Point& operator-=(const Point& p) {
		x -= p.x;
		y -= p.y;
		return *this;
	}
	constexpr Point& operator*=(const Point& p) {
		x *= p.x;
		y *= p.y;
		return *this;
	}
	constexpr Point& operator/=(const Point& p) {
		x /= p.x;
		y /= p.y;
		return *this;
	}
	constexpr Point& operator%=(const Point& p) {
		x %= p.x;
		y %= p.y;
		return *this;
	}
	constexpr Point& operator+=(int n) {
		x += n;
		y += n;
		return *this;
	}
	constexpr Point& operator-=(int n) {
		x -= n;
		y -= n;
		return *this;
	}
	constexpr Point& operator*=(int n) {
		x *= n;
		y *= n;
		return *this;
	}
	constexpr Point& operator/=(int n) {
		x /= n;
		y /= n;
		return *this;
	}
	constexpr Point& operator%=(int n) {
		x %= n;
		y %= n;
		return *this;
	}
	constexpr bool operator==(const Point& p) const {
		return x == p.x && y == p.y;
	}
	constexpr bool operator!=(const Point& p) const {
		return x != p.x || y != p.y;
	}
	bool operator<(const Point& p) const {
		return to_i() < p.to_i();
	}
	bool operator<=(const Point& p) const {
		return to_i() <= p.to_i();
	}
	bool operator>(const Point& p) const {
		return to_i() > p.to_i();
	}
	bool operator>=(const Point& p) const {
		return to_i() >= p.to_i();
	}
	constexpr int operator[](int i) const {
		return i == 0 ? x : i == 1 ? y : 0;
	}
	constexpr bool in_range(int height, int width) const {
		return 0 <= x && x < width && 0 <= y && y < height;
	}
	bool in_range() const {
		return in_range(H, W);
	}
	int to_i() const {
		return x + y * W;
	}
	constexpr pair<int, int> to_pair() const {
		return {x, y};
	}
	int manhattan_distance(const Point& p) const {
		return std::abs(x - p.x) + std::abs(y - p.y);
	}
	int distance_square(const Point& p) const {
		return (x - p.x) * (x - p.x) + (y - p.y) * (y - p.y);
	}
	template <class Real> Real distance(const Point& p) const {
		return sqrt(static_cast<Real>(distance_square(p)));
	}
	Point abs(const Point& p) const {
		return {std::abs(x - p.x), std::abs(y - p.y)};
	}
	Point abs() const {
		return {std::abs(x), std::abs(y)};
	}
	Point& swap() {
		std::swap(x, y);
		return *this;
	}

	class enumrate_adjacent_helper {
		shared_ptr<Point> p;
		direction_iterator first, last;

		class iterator {
			shared_ptr<Point> p;
			direction_iterator it;

		public:
			iterator(shared_ptr<Point> _p, direction_iterator _it) : p(_p), it(_it) {}
			Point operator*() const {
				return *p + *it;
			}
			iterator& operator++() {
				++it;
				return *this;
			}
			bool operator!=(iterator other) const {
				return it != other.it;
			}
		};

	public:
		enumrate_adjacent_helper(shared_ptr<Point> _p, direction_iterator _first,
		                         direction_iterator _last)
		    : p(_p), first(_first), last(_last) {}
		iterator begin() const {
			return iterator(p, first);
		}
		iterator end() const {
			return iterator(p, last);
		}
	};
	auto enumrate_adjacent(direction_iterator first, direction_iterator last) const {
		return enumrate_adjacent_helper(make_shared<Point>(*this), first, last);
	}
	auto adjacent4() const {
		return enumrate_adjacent(direction.begin(), direction.begin() + 4);
	}
	auto adjacent8() const {
		return enumrate_adjacent(direction.begin(), direction.begin() + 8);
	}

	class enumrate_adj_in_range_helper {
		shared_ptr<Point> p;
		direction_iterator first, last;

		class sentinel {};
		class iterator {
			shared_ptr<Point> p;
			direction_iterator first, last;

			void increment_until_in_range() {
				for (; first != last; ++first) {
					if ((*p + *first).in_range()) return;
				}
			}

		public:
			iterator(shared_ptr<Point> _p, direction_iterator _first,
			         direction_iterator _last)
			    : p(_p), first(_first), last(_last) {
				increment_until_in_range();
			}
			Point operator*() const {
				return *p + *first;
			}
			iterator& operator++() {
				++first;
				increment_until_in_range();
				return *this;
			}
			bool operator!=(sentinel other) const {
				return first != last;
			}
		};

	public:
		enumrate_adj_in_range_helper(shared_ptr<Point> _p, direction_iterator _first,
		                             direction_iterator _last)
		    : p(_p), first(_first), last(_last) {}
		iterator begin() const {
			return iterator(p, first, last);
		}
		sentinel end() const {
			return sentinel();
		}
	};
	template <class InputIterator>
	auto enumrate_adj_in_range(InputIterator first, InputIterator last) const {
		return enumrate_adj_in_range_helper(make_shared<Point>(*this), first, last);
	}
	auto adj4_in_range() const {
		return enumrate_adj_in_range(direction.begin(), direction.begin() + 4);
	}
	auto adj8_in_range() const {
		return enumrate_adj_in_range(direction.begin(), direction.end());
	}

	constexpr Point left() const {
		return {x - 1, y};
	}
	constexpr Point right() const {
		return {x + 1, y};
	}
	constexpr Point up() const {
		return {x, y - 1};
	}
	constexpr Point down() const {
		return {x, y + 1};
	}
	Point succ() const {
		if (x != W - 1) {
			return {x + 1, y};
		} else {
			return {0, y + 1};
		}
	}
	Point pred() const {
		if (x != 0) {
			return {x - 1, y};
		} else {
			return {W - 1, y - 1};
		}
	}
	constexpr Point moved(char c) const {
		return Point(*this).move(c);
	}
	constexpr Point& move(char c) {
		switch (c) {
			case 'L':
			case 'l':
			case 'W':
			case '>':
				x--;
				break;
			case 'R':
			case 'r':
			case 'E':
			case '<':
				x++;
				break;
			case 'U':
			case 'u':
			case 'N':
			case '^':
				y--;
				break;
			case 'D':
			case 'd':
			case 'S':
			case 'v':
				y++;
				break;
		}
		return *this;
	}
	constexpr Point rotate90() const {
		return {y, -x};
	}
	constexpr Point rotate180() const {
		return {-x, -y};
	}
	constexpr Point rotate270() const {
		return {-y, x};
	}
	char to_direction_char(string_view lrud = "LRUD") const {
		assert(4 <= lrud.size() && lrud.size() <= 5);
		if (y == 0 && x < 0) {
			return lrud[0];
		} else if (y == 0 && x > 0) {
			return lrud[1];
		} else if (x == 0 && y < 0) {
			return lrud[2];
		} else if (x == 0 && y > 0) {
			return lrud[3];
		} else if (lrud.size() == 5) {
			return lrud[4];
		} else {
			assert(false);
		}
	}

	static Point to_direction(char c, string_view lrud = "LRUD") {
		assert(lrud.size() == 4);
		if (c == lrud[0]) {
			return L();
		} else if (c == lrud[1]) {
			return R();
		} else if (c == lrud[2]) {
			return U();
		} else if (c == lrud[3]) {
			return D();
		} else {
			return zero();
		}
	}

	template <class T, class value_type = typename T::value_type::value_type>
	static optional<Point> find(const T& grid, const value_type& val) {
		assert(static_cast<int>(grid.size()) == H);
		for (int i = 0; i < H; ++i) {
			assert(static_cast<int>(grid[i].size()) == W);
			for (int j = 0; j < W; ++j) {
				if (grid[i][j] == val) {
					return Point(j, i);
				}
			}
		}
		return nullopt;
	}
	template <class T, class Predicate>
	static optional<Point> find_if(const T& grid, Predicate pred) {
		assert(static_cast<int>(grid.size()) == H);
		for (int i = 0; i < H; ++i) {
			assert(static_cast<int>(grid[i].size()) == W);
			for (int j = 0; j < W; ++j) {
				if (pred(grid[i][j])) {
					return Point(j, i);
				}
			}
		}
		return nullopt;
	}
	template <class T, class value_type = typename T::value_type::value_type>
	static optional<Point> find_one(const T& grid, const value_type& val) {
		assert(static_cast<int>(grid.size()) == H);
		optional<Point> result;
		for (int i = 0; i < H; ++i) {
			assert(static_cast<int>(grid[i].size()) == W);
			for (int j = 0; j < W; ++j) {
				if (grid[i][j] == val) {
					assert(!result);
					result = Point(j, i);
				}
			}
		}
		return result;
	}

	static auto enumrate_2D_points() {
		class enumrate_2D_points_helper {
		public:
			class iterator {
				Point p;

			public:
				iterator(const Point& _p) : p(_p) {}
				Point operator*() const {
					return p;
				}
				iterator& operator++() {
					p = p.succ();
					return *this;
				}
				iterator& operator--() {
					p = p.pred();
					return *this;
				}
				bool operator!=(iterator other) const {
					return p != other.p;
				}
			};
			iterator begin() const {
				return iterator(Point(0, 0));
			}
			iterator end() const {
				return iterator(Point(0, H));
			}
		};
		return enumrate_2D_points_helper();
	}

	friend ostream& operator<<(ostream& os, const Point& p) {
		return os << '(' << p.x << ", " << p.y << ')';
	}
	friend istream& operator>>(istream& is, Point& p) {
		return is >> p.y >> p.x;
	}
};
int Point::H, Point::W;
const vector<Point> Point::direction{Point::R(),  Point::D(),  Point::U(),  Point::L(),
                                     Point::RD(), Point::LU(), Point::RU(), Point::LD()};
#line 3 "a.cpp"

int solve(int w, int h) {
	vector<vector<string>> s = in[{h, w}];
	Point::set_range(h, w);
	int n = 0;
	rep(i, h) rep(j, w) {
		try {
			int val = stoi(s[i][j]);
			chmax(n, val);
		} catch (...) {
		}
	}

	vector<vector<Point>> points(n + 2);
	points.front().push_back(Point::find(s, "S").value());
	points.back().push_back(Point::find(s, "G").value());
	for (Point p : Point::enumrate_2D_points()) {
		string c = s[p.y][p.x];
		try {
			int c_val = stoi(c);
			points[c_val].push_back(p);
		} catch (...) {
		}
	}

	VVI dp(n + 2);
	dp[0].push_back(0);
	FOR(i, 1, n + 2) {
		int s1 = points[i - 1].size(), s2 = points[i].size();
		dp[i].assign(s2, inf);
		rep(j, s1) rep(k, s2) {
			chmin(dp[i][k],
			      dp[i - 1][j] + points[i - 1][j].manhattan_distance(points[i][k]));
		}
	}
	return dp.back().front();
}

int main() {
	while (true) {
		ini(x, y);
		if (x + y == 0) break;
		out(solve(x, y));
	}
}
accuracy: 1
time_ms: 80
memory_kb: 3912
final_rank: 15

code_snippet: #include<iostream>
#include<vector>
#include<cctype>
using namespace std;

int main(){
    int w, h;
    while(cin >> w >> h, w+h){
        vector<int> xi[2525], yj[2525];
        vector<vector<int>> dp(2525, vector<int>(2525,1<<30));
        int gi = -1, gj = -1, ma = 0;
        for(int i = 0; i < h; i++){
            for(int j = 0; j < w; j++){
                string s;   cin >> s;
                if(isdigit(s[0])){
                    int num = stoi(s);
                    ma = max(ma, num);
                    xi[num].push_back(i), yj[num].push_back(j);
                }else if(s == "S"){
                    xi[0].push_back(i), yj[0].push_back(j);
                }else if(s == "G"){
                    gi = i, gj = j;
                }
            }
        }
        ma++;
        xi[ma].push_back(gi), yj[ma].push_back(gj);
        dp[0][0] = 0;
        for(int i = 0; xi[i+1].size(); i++){
            for(int j = 0; j < xi[i].size(); j++){
                for(int k = 0; k < xi[i+1].size(); k++){
                    dp[i+1][k] = min(dp[i+1][k], dp[i][j] + abs(xi[i][j]-xi[i+1][k])+abs(yj[i][j]-yj[i+1][k]));
                }
            }
        }
        cout << dp[ma][0] << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 280
memory_kb: 28428
final_rank: 18

code_snippet: #include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cctype>
#include<math.h>
#include<string>
#include<string.h>
#include<stack>
#include<queue>
#include<vector>
#include<utility>
#include<set>
#include<map>
#include<stdlib.h>
#include<iomanip>

using namespace std;

#define ll long long
#define ld long double
#define EPS 0.0000000001
#define INF 1e9
#define LINF (ll)INF*INF
#define MOD 1000000007
#define rep(i,n) for(int i=0;i<(n);i++)
#define loop(i,a,n) for(int i=a;i<(n);i++)
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)

#define int ll //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int,int> pii;
typedef vector<pii> vp;

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


struct edge { int to, cost;};

class Dijkstra{
private:
    vector< vector<edge> > g;

public:
    Dijkstra(){};
    Dijkstra(int size){
        g.resize(size);
    }

    vi dist;

    void add(int a, int b, int c){//無向辺
        edge e1 = {b, c}, e2 = {a, c};
        g[a].push_back(e1);
        //g[b].push_back(e2);//有向辺の場合はここをコメントアウトする
    }

    void calc(int s){
        priority_queue< pii, vector<pii>, greater<pii> > q;
        int n = g.size();
        dist = vi (n, INF);
        dist[s] = 0;
        q.push(pii(0, s));

        while(!q.empty()){
            pii p = q.top();
            q.pop();
            int v = p.second;
            if(dist[v] < p.first)continue; //更新されていたら何もしない
            for(int i = 0; i < g[v].size(); i++){
                edge e = g[v][i];
                if(dist[e.to] > dist[v] + e.cost){
                    dist[e.to] = dist[v] + e.cost;
                    q.push(pii(dist[e.to], e.to));
                }
            }
        }
    }

};


int h,w;

int f(pii p){
    return p.first * w + p.second;
}
int g(pii x, pii y){
    return abs(x.first - y.first) + abs(x.second - y.second);
}
int num(string s){
    int ret = 0;
    rep(i,s.size()){
        ret *= 10;
        ret += s[i] - '0';
    }
    return ret;
}

signed main(void) {
    while(cin >> w >> h, h){
        int sx,sy,gx,gy;
        vector<vp> v(h*w);
        rep(i,h)rep(j,w){
            string in;
            cin >> in;
            if(in == ".");
            else if(in == "S")sx = i, sy = j;
            else if(in == "G")gx = i, gy = j;
            else v[num(in)].push_back(pii(i,j));
        }
        v[0].push_back(pii(sx,sy));
        int ind = 0;
        while(v[ind].size())ind++;
        v[ind].push_back(pii(gx,gy));
        while(v.back().size() == 0)v.pop_back();
        /*
        rep(i,v.size()){
            cout << i << endl;
            rep(j,v[i].size())cout << v[i][j].first << " " << v[i][j].second << endl;
        }
        */
        Dijkstra dij(h*w);
        rep(i,v.size()-1){
            rep(j,v[i].size())rep(k,v[i+1].size()){
                //v[i][j]からv[i+1][k]に辺をはる
                dij.add(f(v[i][j]),f(v[i+1][k]), g(v[i][j],v[i+1][k]));
            }
        }
        dij.calc(f(v.front().front()));
        cout << dij.dist[f(v.back().front())] << endl;
    }

}
accuracy: 1
time_ms: 20
memory_kb: 10060
final_rank: 14

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
#include<utility>
#include<string>
#include<cmath>
#include<cstring>
#include<queue>
#include<map>
#include<climits>
#include<set>

#define REP(i, n) for(int i = 0;i < n;i++)
#define REPR(i, n) for(int i = n;i >= 0;i--)
#define FOR(i, m, n) for(int i = m;i < n;i++)
#define FORR(i, m, n) for(int i = m;i >= n;i--)
#define SORT(v, n) sort(v, v+n);
#define VSORT(v) sort(v.begin(), v.end());
#define llong long long
#define pb(a) push_back(a)
using namespace std;
typedef pair<int, int> pii;
typedef long long int ll;
typedef pair<ll,ll> pll;
int dx[4] = {1,0,0,-1};
int dy[4] = {0,1,-1,0};
#define MOD 1000000007
#define ARRAY_MAX 3000

const int INF = 1e9+7;


int main(){

    int w,h;
    while(cin >> w >> h,w|h){

        vector<pll> g[ARRAY_MAX];
        ll gy,gx,n = 0;
        for(int i = 0;i < h;i++){
            for(int j = 0;j < w;j++){
                string s;
                cin >> s;
                if(s == "."){
                    continue;
                }
                if(s == "S"){
                    g[0].push_back({i,j});
                }else if(s == "G"){
                    gy = i;
                    gx = j;
                }else{
                    ll num = (ll)stoi(s);
                    g[num].push_back({i,j});
                    n = max(n,num);//最大の数字
                }
            }
        }
        n++;
        g[n].push_back({gy,gx});
        vector<vector<ll> > dp(n+1);
        for(int i = 0;i < n+1;i++){
            dp[i].resize(g[i].size(),INF);
        }
        dp[0][0] = 0;
        //dp[Y][X]:数字Yのついた地点のX個目の地点までの最短距離

        for(int i = 1;i <= n;i++){
            for(int j = 0;j < g[i-1].size();j++){
                for(int k = 0;k < g[i].size();k++){
                    ll len = abs(g[i-1][j].first-g[i][k].first) + abs(g[i-1][j].second-g[i][k].second);
                    dp[i][k] = min(dp[i][k],dp[i-1][j] + len);
                }
            }
        }
        cout << dp[n][0] << endl;
    }

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

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
#include<utility>
#include<string>
#include<cmath>
#include<cstring>
#include<queue>
#include<map>
#include<climits>
#include<set>

#define REP(i, n) for(int i = 0;i < n;i++)
#define REPR(i, n) for(int i = n;i >= 0;i--)
#define FOR(i, m, n) for(int i = m;i < n;i++)
#define FORR(i, m, n) for(int i = m;i >= n;i--)
#define SORT(v, n) sort(v, v+n);
#define VSORT(v) sort(v.begin(), v.end());
#define llong long long
#define pb(a) push_back(a)
using namespace std;
typedef pair<int, int> pii;
typedef long long int ll;
typedef pair<ll,ll> pll;
int dx[4] = {1,0,0,-1};
int dy[4] = {0,1,-1,0};
#define MOD 1000000007
#define ARRAY_MAX 3000

const int INF = 1e9+7;


int main(){

    int w,h;
    while(cin >> w >> h,w|h){

        vector<pll> g[ARRAY_MAX];
        ll gy,gx,n = 0;
        for(int i = 0;i < h;i++){
            for(int j = 0;j < w;j++){
                string s;
                cin >> s;
                if(s == "."){
                    continue;
                }
                if(s == "S"){
                    g[0].push_back({i,j});
                }else if(s == "G"){
                    gy = i;
                    gx = j;
                }else{
                    ll num = (ll)stoi(s);
                    g[num].push_back({i,j});
                    n = max(n,num);//最大の数字
                }
            }
        }
        n++;
        g[n].push_back({gy,gx});
        vector<vector<ll> > dp(n+1);
        for(int i = 0;i < n+1;i++){
            dp[i].resize(g[i].size(),INF);
        }
        dp[0][0] = 0;

        for(int i = 1;i <= n;i++){
            for(int j = 0;j < g[i-1].size();j++){
                for(int k = 0;k < g[i].size();k++){
                    ll len = abs(g[i-1][j].first-g[i][k].first) + abs(g[i-1][j].second-g[i][k].second);
                    dp[i][k] = min(dp[i][k],dp[i-1][j] + len);
                }
            }
        }
        cout << dp[n][0] << endl;
    }

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

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;
const ll MOD = 1000000007;
const int IINF = INT_MAX;
const ll LLINF = LLONG_MAX;
const int MAX_N = int(2e5 + 5);
const double EPS = 1e-8;
const int di[] = {0, 1, 0, -1}, dj[] = {1, 0, -1, 0};
#define REP(i, n) for (int i = 0; i < n; i++)
#define REPR(i, n) for (int i = n; i >= 0; i--)
#define SORT(v) sort((v).begin(), (v).end())
#define ALL(v) (v).begin(), (v).end()

int main() {
    int h, w;
    while(cin >> w >> h, h){
        vector<P> g[10005];
        ll n=0, gi, gj;
        REP(i,h)REP(j,w){
            string s;
            cin >> s;
            if(s=="."){
                continue;
            }
            else if(s=="S")g[0].push_back({i,j});
            else if(s=="G"){
                gi = i;
                gj = j;
            }
            else{
                ll num = stoi(s);
                g[num].push_back({i,j});
                n = max(n,num);
            }
        }
        n++;
        g[n].push_back({gi,gj});
        vector<vector<ll>> dp(n+1);
        REP(i,n+1) dp[i].resize(g[i].size(),LLINF/3);
        dp[0][0] = 0;
        REP(i,n){
            REP(j,g[i].size()){
                REP(k,g[i+1].size()){
                    ll d = abs(g[i][j].first-g[i+1][k].first) + abs(g[i][j].second-g[i+1][k].second);
                    dp[i+1][k] = min(dp[i+1][k],dp[i][j] + d);
                }
            }
        }
        cout << dp[n][0] << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3456
final_rank: 6

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

#define lint long long
#define P pair<int, int>
#define LLP pair<long long, long long>
#define REP(i, x, n) for(int i = (x), i##_len = (int)(n) ; i < i##_len ; ++i)
#define rep(i, n) for(int i = 0, i##_len = (int)(n) ; i < i##_len ; ++i)
#define repr(i, n) for(int i = (int)(n) - 1 ; i >= 0 ; --i)
#define SORT(x) sort((x).begin(), (x).end())
#define SORT_INV(x) sort((x).rbegin(), (x).rend())

const int IINF = 1e9 + 10;
const long long LLINF = (long long)1e18 + 10;
const long long MOD = (long long)1e9 + 7;
const int dx4[] = {1, 0, -1, 0}, dy4[] = {0, 1, 0, -1};
const int dx8[] = {1, 1, 0, -1, -1, -1, 0, 1}, dy8[] = {0, -1, -1, -1, 0, 1, 1, 1};
const double EPS = 1e-8;

#define int long long

int w, h;
vector< vector<string> > s;
vector< vector< P > > v(2500);
int sy, sx, gy, gx;
int maxi;
int memo[2525][2525];

int solve(int i, int j){
    if(i == maxi + 1){
        return 0;
    }
    if(memo[i][j] >= 0){
        return memo[i][j];
    }

    int res = LLINF;
    rep(k, v[i + 1].size()){
        res = min(res, solve(i + 1, k) + abs(v[i][j].first - v[i + 1][k].first) + abs(v[i][j].second - v[i + 1][k].second));
    }
    return memo[i][j] = res;
}

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

    while(cin >> w >> h, w){

        rep(i, 2500){
            v[i].clear();
        }

        maxi = 0;

        fill(memo[0], memo[2525], -1);

        s.resize(h);
        rep(i, h){
            s[i].resize(w);
            rep(j, w){
                cin >> s[i][j];
                if(s[i][j] == "S"){
                    sy = i;
                    sx = j;
                }else if(s[i][j] == "G"){
                    gy = i;
                    gx = j;
                }else if(s[i][j] != "."){
                    int num = 0;
                    for(auto x : s[i][j]){
                        num *= 10;
                        num += x - '0';
                    }
                    maxi = max(maxi, num);
                    v[num].push_back({i, j});
                }
            }
        }

        v[0].push_back({sy, sx});
        v[maxi + 1].push_back({gy, gx});

        int ans = solve(0, 0);
        cout << ans << endl;
        
    }

    return 0;
}
accuracy: 1
time_ms: 430
memory_kb: 53460
final_rank: 20

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 INF = INT_MAX/3;

int dist(pi p, pi q){
    return abs(p.fi-q.fi) + abs(p.se-q.se);
}

bool isnumber(string s){
    return isdigit(s[0]);
}

int main(){
    int w,h;
    while(cin >>w >>h,w){
        vector<vector<string>> s(h, vector<string>(w));
        rep(i,h)rep(j,w) cin >>s[i][j];

        int mx = 0;
        rep(i,h)rep(j,w)if(isnumber(s[i][j])) mx = max(mx, stoi(s[i][j]));

        vector<vector<pi>> pos(mx+2);
        rep(i,h)rep(j,w){
            if(isnumber(s[i][j])) pos[stoi(s[i][j])].pb({i,j});
            else if(s[i][j]=="S") pos[0].pb({i,j});
            else if(s[i][j]=="G") pos[mx+1].pb({i,j});
        }

        vector<int> dp(1,0);
        for(int i=1; i<=mx+1; ++i){
            int P = pos[i-1].size();
            int Q = pos[i].size();

            vector<int> nx(Q,INF);
            rep(j,P)rep(k,Q){
                nx[k] = min(nx[k], dp[j]+dist(pos[i-1][j], pos[i][k]));
            }

            dp = nx;
        }
        cout << dp[0] << "\n";
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3288
final_rank: 2

code_snippet: #include <bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;
typedef pair<int,int> P;
vector<P>v[100001];
vector<int> dp[10001];
int get(string x){
  int res=0;
  r(i,x.size())res=res*10+(x[i]-'0');
  return res;
}
int dist(P a,P b){
  return abs(a.first-b.first)+abs(a.second-b.second);
}
string s;
int e,w,h;
int main(){
  while(cin>>w>>h,h){
    r(i,100001)v[i].clear();
    r(i,10001)dp[i].clear();
    P t;
    r(i,h)r(j,w){
      cin>>s;
      if(s=="G")t=P(i,j);
      if(s=="S")v[0].push_back(P(i,j));
      if(isdigit(s[0])){
        int x=get(s);
        v[x].push_back(P(i,j));
        dp[x].push_back(1e9);
      }
    }
    r(i,99999)if(v[i].size()==0){
      v[i].push_back(t);
      dp[i].push_back(1e9);
      e=i;
      break;
    }
    dp[0].push_back(0);
    r(i,e)r(j,v[i].size())r(k,v[i+1].size())
      dp[i+1][k]=min(dp[i+1][k],dp[i][j]+dist(v[i][j],v[i+1][k]));
    cout<<dp[e][0]<<endl;
  }
}
accuracy: 1
time_ms: 10
memory_kb: 5960
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int,int> P;
#define Y first
#define X second
signed main(){
  int w,h;
  while(cin>>w>>h,w||h){
    string s[h][w];
    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++)
    cin>>s[i][j];
    vector<P> v[50000];
    int gy,gx,gd=0;
    for(int i=0;i<h;i++){
      for(int j=0;j<w;j++){
    if(s[i][j]==".") continue;
    if(s[i][j]=="S"){
      v[0].push_back(P(i,j));
      continue;
    }
    if(s[i][j]=="G"){
      gy=i;gx=j;
      continue;
    }
    int k=stoi(s[i][j]);
    v[k].push_back(P(i,j));
    gd=max(gd,k);
      }
    }
    v[++gd].push_back(P(gy,gx));
    int dp[h][w];
    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++)
    dp[i][j]=1LL<<55LL;
    dp[v[0][0].Y][v[0][0].X]=0;
    for(int i=0;i<gd;i++){
      for(int j=0;j<(int)v[i].size();j++){
    for(int k=0;k<(int)v[i+1].size();k++){
      int cost=abs(v[i+1][k].Y-v[i][j].Y)+abs(v[i+1][k].X-v[i][j].X);
      dp[v[i+1][k].Y][v[i+1][k].X]=
        min(dp[v[i+1][k].Y][v[i+1][k].X],dp[v[i][j].Y][v[i][j].X]+cost);
    }
      }
    }
    cout<<dp[v[gd][0].Y][v[gd][0].X]<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 4544
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int,int> P;
#define Y first
#define X second
signed main(){
  int w,h;
  while(cin>>w>>h,w||h){
    string s[h][w];
    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++)
	cin>>s[i][j];
    vector<P> v[50000];
    int gy,gx,gd=0;
    for(int i=0;i<h;i++){
      for(int j=0;j<w;j++){
	if(s[i][j]==".") continue;
	if(s[i][j]=="S"){
	  v[0].push_back(P(i,j));
	  continue;
	}
	if(s[i][j]=="G"){
	  gy=i;gx=j;
	  continue;
	}
	int k=stoi(s[i][j]);
	v[k].push_back(P(i,j));
	gd=max(gd,k);
      }
    }
    v[++gd].push_back(P(gy,gx));
    int dp[h][w];
    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++)
	dp[i][j]=1LL<<55LL;
    dp[v[0][0].Y][v[0][0].X]=0;
    for(int i=0;i<gd;i++){
      for(int j=0;j<(int)v[i].size();j++){
	for(int k=0;k<(int)v[i+1].size();k++){
	  int cost=abs(v[i+1][k].Y-v[i][j].Y)+abs(v[i+1][k].X-v[i][j].X);
	  dp[v[i+1][k].Y][v[i+1][k].X]=
	    min(dp[v[i+1][k].Y][v[i+1][k].X],dp[v[i][j].Y][v[i][j].X]+cost);
	}
      }
    }
    cout<<dp[v[gd][0].Y][v[gd][0].X]<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 4524
final_rank: 11

code_snippet: #include <queue>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
const vector<int> dir = { 1, 0, -1, 0 };
int H, W; string s[109][109];
int main() {
	while (cin >> W >> H, H | W) {
		int sx, sy, gx, gy, cnt = 0;
		for (int i = 0; i < H; i++) {
			for (int j = 0; j < W; j++) {
				cin >> s[i][j];
				if (s[i][j] == "S") sx = j, sy = i;
				if (s[i][j] == "G") gx = j, gy = i;
				if (isdigit(s[i][j][0])) cnt = max(cnt, stoi(s[i][j]));
			}
		}
		vector<vector<int> > px(cnt + 2), py(cnt + 2);
		for (int i = 0; i < H; i++) {
			for (int j = 0; j < W; j++) {
				int val = -1;
				if (s[i][j] == "S") val = 0;
				if (s[i][j] == "G") val = cnt + 1;
				if (isdigit(s[i][j][0])) val = stoi(s[i][j]);
				if (val >= 0) {
					px[val].push_back(j);
					py[val].push_back(i);
				}
			}
		}
		vector<vector<int> > dp(cnt + 2);
		dp[0] = { 0 };
		for (int i = 1; i <= cnt + 1; i++) {
			dp[i].resize(px[i].size(), 999999999);
			for (int j = 0; j < dp[i].size(); j++) {
				for (int k = 0; k < dp[i - 1].size(); k++) {
					int dist = abs(px[i][j] - px[i - 1][k]) + abs(py[i][j] - py[i - 1][k]);
					dp[i][j] = min(dp[i][j], dp[i - 1][k] + dist);
				}
			}
		}
		cout << dp[cnt + 1][0] << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3596
final_rank: 8

code_snippet: #include<bits/stdc++.h>
#define rep(i,n)for(int i=0;i<n;i++)
using namespace std;

vector<int>x[2502], y[2502];
int d[2502][2502];
int p;

int main() {
	int w, h;
	while (scanf("%d%d", &w, &h), w) {
		rep(i, 2502) {
			x[i].clear(); y[i].clear();
		}
		p = 1;//s->0,g->p
		int gx, gy;
		rep(i, h) {
			rep(j, w) {
				string s; cin >> s;
				if (s == ".");
				else if (s == "S")
					x[0].push_back(i), y[0].push_back(j);
				else if (s == "G")gx = i, gy = j;
				else {
					int d = stoi(s); p = max(p, d + 1);
					x[d].push_back(i); y[d].push_back(j);
				}
			}
		}
		x[p].push_back(gx); y[p].push_back(gy);
		memset(d, 0x3f, sizeof(d));
		d[0][0] = 0;
		for (int i = 1; i <= p; i++) {
			rep(j, x[i].size()) {
				rep(k, x[i - 1].size()) {
					d[i][j] = min(d[i][j], d[i - 1][k] + abs(x[i - 1][k] - x[i][j]) + abs(y[i - 1][k] - y[i][j]));
				}
			}
		}
		printf("%d\n", d[p][0]);
	}
}
accuracy: 1
time_ms: 90
memory_kb: 28004
final_rank: 16

code_snippet: #include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#define p pair<int,int>
#define P pair<p,int>
using namespace std;

int parse(string a) {
	int b = 0;
	for (char c : a)b = b * 10 + c - 48;
	return b;
}
int main() {
	int a, b;
	while (cin>>b>>a, a | b) {
		p G;
		vector<P>d[20000];
		int MAX = 0;
		for (int e = 0; e < a; e++) {
			for (int g = 0; g < b; g++) {
				string o;
				cin >> o;
				if (o=="S")d[0].push_back(P(p(e,g), 0));
				else if (o=="G")G = p(e, g);
				else if (o!=".") {
					d[parse(o)].push_back(P(p(e, g), 0));
					MAX = max(MAX, parse(o));
				}
			}
		}
		for (int i = 1; i <= MAX; i++) {
			for (int j = 0; j < d[i].size();j++) {
				int MIN = 1 << 29;
				for (int k = 0; k < d[i - 1].size(); k++) {
					MIN = min(MIN, d[i - 1][k].second + abs(d[i][j].first.first- d[i - 1][k].first.first) + abs(d[i][j].first.second - d[i - 1][k].first.second));
				}
				d[i][j].second = MIN;
			}
		}
		int MINCOST = 1 << 29;
		for (P s : d[MAX]) {
			MINCOST = min(MINCOST, s.second + abs(G.first-s.first.first) + abs(G.second-s.first.second));
		}
		cout << MINCOST << endl;
	}
}
accuracy: 1
time_ms: 10
memory_kb: 3600
final_rank: 9

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

#define REP(i, s, e) for(int i = (int)s; i < (int) e; i++)
#define rep(i, n) REP(i, 0 ,n)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()

#define fi first
#define se second
#define pb push_back
#define mp nake_pair

typedef long long ll;
typedef vector<int> vi;

string s;
int perseInt(const string& s){
    int ret = 0;
    rep(i, s.size()) ret = ret *10 + (s[i]-'0');
    return ret;
}

struct P{
    int x, y;
    P(){};
    P(int x, int y) : x(x), y(y){};
    int dist(const P& p){
        return abs(x-p.x)+abs(y-p.y);
    }
};
vector<P> ps[2600];

int main(){
    int w, h;
    while(cin>>w>>h && w && h){
        int m = 0;
        P g;
        rep(i, 2600) ps[i].clear();
        rep(i, h) rep(j, w){
            cin>>s;
            if(s == ".") continue;
            else if(s == "S") ps[0].pb({i, j});
            else if(s == "G") g = {i, j};
            else {
                int k = perseInt(s);
                ps[k].pb({i, j});
                m = max(m, k);
            }
        }
        ps[++m].pb(g);
        vector<vi> d(2600, vi(2600, 1e9));
        d[0][0] = 0;
        rep(i, m){
            rep(j, ps[i].size()){
                rep(k, ps[i+1].size()){
                    d[i+1][k] = min(d[i+1][k], d[i][j]+ps[i][j].dist(ps[i+1][k]));
                }
            }
        }
        cout<<d[m][0]<<endl;
    }
}
accuracy: 1
time_ms: 310
memory_kb: 29612
final_rank: 19

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <sstream>
#include <cstring>
  
using namespace std;
  
#define MAX 10000
#define INF 1e9
typedef pair<int,int> P;
int ans, N;
vector<P> vec[MAX];
int dp[100][100]; 
 
int dist(int x1, int y1, int x2, int y2){
    return abs(x1-x2) + abs(y1-y2);
}
 
int getNum(string &s){
    stringstream ss(s);
    int res;
    ss >> res;
    return res;
}
  
int main(){
    int W, H;
  
    while(cin >> W >> H, (W | H)){
	string in;
	int gx, gy, max = 0;
	for(int i = 0 ; i < MAX ; i++){
	    vec[i].clear();
	}
	for(int i = 0 ; i < H ; i++){
	    for(int j = 0 ; j < W ; j++){
		cin >> in;
		if(in == ".") continue;
		if(in == "S"){
		    vec[0].push_back(P(i,j));
		}else if(in == "G"){
		    gx = i, gy = j;
		}else{
		    int num = getNum(in);
		    max = std::max(max, num);
		    vec[num].push_back(P(i,j));
		}
	    }
	}
	vec[max+1].push_back(P(gx,gy));
	ans = INF; N = max+2;
	fill(dp[0],dp[H],INF);
	for(int i = 0 ; i < N-1 ; i++){
	    for(int j = 0 ; j < vec[i+1].size() ; j++){
		for(int k = 0 ; k < vec[i].size() ; k++){
		    int bx = vec[i][k].first;
		    int by = vec[i][k].second;
		    int nx = vec[i+1][j].first;
		    int ny = vec[i+1][j].second;
		    if(dp[bx][by] == INF) dp[bx][by] = 0;
		    dp[nx][ny] = min(dp[nx][ny],dp[bx][by] + dist(bx,by,nx,ny));;
		}
	    }
	}
	cout << dp[gx][gy] << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3540
final_rank: 7

code_snippet: #include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<utility>
#include<cmath>
#include<cstring>
#include<queue>
#include<cstdio>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define mp make_pair
#define all(in) in.begin(),in.end()
const double PI=acos(-1);
const double EPS=1e-10;
const int inf=1e9;
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> pii;
int main(){
	int n,m;
	while(cin>>m>>n,n+m){
		vvi in(n,vi(m));
		int sx,sy,gx,gy;
		rep(i,n)rep(j,m){
			string s;
			cin>>s;
			if(s==".")in[i][j]=0;
			else if(s=="G"){gx=i,gy=j;}
			else if(s=="S"){sx=i;sy=j;}
			else in[i][j]=atoi(&s[0]);

		}
		vector<pii>now;
		now.pb(pii(sx*10000+sy,0));
		int co=1;
		while(1){
			vector<pii>next;
			bool h=false;
			rep(i,n)rep(j,m)if(in[i][j]==co){
				h=true;
				int mi=inf;
				rep(k,now.size()){
					mi=min(mi,
					now[k].second+abs(i-now[k].first/10000)+abs(j-now[k].first%10000));
				}
				next.pb(pii(i*10000+j,mi));
			}
			if(!h)break;
			co++;
			now=next;
		}
		int mi=inf;
		rep(i,now.size())mi=min(mi,abs(gx-now[i].first/10000)+abs(gy-now[i].first%10000)+now[i].second);
		cout<<mi<<endl;
	}
}
accuracy: 1
time_ms: 30
memory_kb: 1280
final_rank: 10