Go: ///
// File:  0558.go
// Author: ymiyamoto
//
// Created on Sun Mar  4 20:58:45 2018
//
package main

import (
	"fmt"
	"strconv"
	"strings"
)

type pos struct {
	x, y int
}

var H, W, N int
var graph [][]string

func wfs(p pos, index int) (int, pos) {
	var q []pos
	dists := make([][]int, H)
	for i := range dists {
		dists[i] = make([]int, W)
	}

	q = append(q, p)
	for len(q) > 0 {
		p := q[0]
		dist := dists[p.x][p.y]
		q = q[1:]

		for _, d := range []pos{{-1, 0}, {1, 0}, {0, -1}, {0, 1}} {
			x := p.x + d.x
			y := p.y + d.y
			if 0 <= x && x < H && 0 <= y && y < W && graph[x][y] != "X" && dists[x][y] == 0 {
				dists[x][y] = dist + 1
				q = append(q, pos{x, y})
			}
		}
	}

	for i := range graph {
		for j := range graph[i] {
			if graph[i][j] == strconv.Itoa(index) {
				return dists[i][j], pos{i, j}
			}
		}
	}

	panic("not found")
}

func main() {
	fmt.Scan(&H, &W, &N)

	var start pos

	graph = make([][]string, H)
	for i := range graph {
		var s string
		fmt.Scan(&s)
		graph[i] = strings.Split(s, "")
		for j := range graph[i] {
			if graph[i][j] == "S" {
				start.x = i
				start.y = j
			}
		}
	}

	count := 0
	for i := 1; i <= N; i++ {
		c, s := wfs(start, i)
		start = s
		count += c
	}

	fmt.Println(count)
}

C++: #include <cstdio>
#include <map>
#include <queue>
#include <string>

using namespace std;

const int INF = 100000000;
const int MAX_H = 1000;
const int MAX_W = 1000;
const int MAX_N = 9;

int H, W, N;
char field[MAX_H][MAX_W];
int d[MAX_H][MAX_W]; // ?????????????????\??´?????§??????????????°, 1~N??§?????????????????§????????°??????+1
int sx, sy, gx, gy;
int power = 1; // ??????????????????
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};

typedef pair<int, int> P;

void reset_d() {
  for (int i = 0; i < H; i++)
    for(int j = 0; j < W; j++) d[i][j] = INF;
}

int bfs(int c) {
  queue<P> que;
  reset_d();
  d[sx][sy] = c;
  que.push(P(sx, sy));
  while(que.size()) {
    P p = que.front(); que.pop();
    for (int i = 0; i < 4; i++) {
      int nx = p.first + dx[i], ny = p.second + dy[i];
      if ( 0 <= nx && nx <= H && 0 <= ny && ny <= W && field[nx][ny] != 'X' && d[nx][ny] == INF) {
        d[nx][ny] = d[p.first][p.second] + 1;
        que.push(P(nx, ny));
        if (field[nx][ny] - '0' == power) {
          sx = nx;
          sy = ny;
          power++;
          return d[nx][ny];
        }
      }
    }
  }
  return INF;
}

void solve() {
  int c = 0;
  for (int i = 0; i < N; i++) {
    c = bfs(c);
  }
  printf("%d\n", c);
}


int main() {
  scanf("%d %d %d", &H, &W, &N);
  for (int i = 0; i < H; i++) {
    scanf("%s", field[i]);
  }
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (field[i][j] == 'S') {
        sx = i;
        sy = j;
      }
      if (field[i][j] == 'G') {
        gx = i;
        gy = j;
      }
    }
  }
  solve();
  return 0;
}

C++: /**
 * File    : JOI_2010_cheese.cpp
 * Author  : Kazune Takahashi
 * Created : 2018-3-8 21:40:42
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

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

// const int C = 1e6+10;
const int infty = 1000000007;

typedef tuple<int, int> point;

int H, W, N;
string S[1010];
int d[1010][1010];
point P[20];
queue<point> Q[20];

bool valid(int x, int y)
{
  return (0 <= x && x < H && 0 <= y && y < W && S[x][y] != 'X');
}

int main()
{
  cin >> H >> W >> N;
  for (auto i = 0; i < H; i++)
  {
    cin >> S[i];
  }
  for (auto i = 0; i < H; i++)
  {
    for (auto j = 0; j < W; j++)
    {
      if (S[i][j] == 'S')
      {
        P[0] = point(i, j);
      }
      int t = S[i][j] - '0';
      if (1 <= t && t <= 9)
      {
        P[t] = point(i, j);
      }
    }
  }
  int ans = 0;
  for (auto i = 0; i < N; i++)
  {
    fill(&d[0][0], &d[0][0] + 1010 * 1010, infty);
    d[get<0>(P[i])][get<1>(P[i])] = 0;
    Q[i].push(P[i]);
    while (!Q[i].empty())
    {
      point p = Q[i].front();
      Q[i].pop();
      if (p == P[i+1])
      {
        ans += d[get<0>(p)][get<1>(p)];
#if DEBUG == 1
        cerr << "d[" << get<0>(p) << "][" << get<1>(p)
             << "] = " << d[get<0>(p)][get<1>(p)] << endl;
#endif
        break;
      }
      for (auto k = 0; k < 4; k++)
      {
        int nx = get<0>(p) + dx[k];
        int ny = get<1>(p) + dy[k];
        if (valid(nx, ny) && d[nx][ny] == infty)
        {
          d[nx][ny] = d[get<0>(p)][get<1>(p)] + 1;
          Q[i].push(point(nx, ny));
        }
      }
    }
  }
  cout << ans << endl;
}

C++: /*
 * hujx.cpp
 *
 *  Created on: 2015年5月21日
 *      Author: dell
 */
#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<time.h>
#include<queue>
#include<stack>
#include<iterator>
#include<math.h>
#include<stdlib.h>
#include<limits.h>
#include<map>
#include<set>
//#define ONLINE_JUDGE
#define eps 1e-8
#define INF 0x7fffffff
#define FOR(i,a) for((i)=0;i<(a);(i)++)
#define MEM(a) (memset((a),0,sizeof(a)))
#define sfs(a) scanf("%s",a)
#define sf(a) scanf("%d",&a)
#define sfI(a) scanf("%I64d",&a)
#define pf(a) printf("%d\n",a)
#define pfI(a) printf("%I64d\n",a)
#define pfs(a) printf("%s\n",a)
#define sfd(a,b) scanf("%d%d",&a,&b)
#define sft(a,b,num) scanf("%d%d%d",&a,&b,&num)
#define for1(i,a,b) for(int i=(a);i<b;i++)
#define for2(i,a,b) for(int i=(a);i<=b;i++)
#define for3(i,a,b)for(int i=(b);i>=a;i--)
#define MEM1(a) memset(a,0,sizeof(a))
#define MEM2(a) memset(a,-1,sizeof(a))
#define ll __int64
const double PI=acos(-1.0);
template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> inline T Min(T a,T b){return a<b?a:b;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
using namespace std;
//#pragma comment(linker,"/STACK:1024000000,1024000000")
int n,m,k;
#define M 110
#define N 500010
#define Mod 258280327
#define p(x,y) make_pair(x,y)
char ch[1010][1010];
int vis[1010][1010];
int posx[15];
int posy[15];
struct Node{
	int x,y;
	int step;
};
bool check(int x,int y){
	if(x<0 || x>=n || y<0 || y>=m || ch[x][y] == 'X' ||vis[x][y])
		return false;
	return true;
}
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
int bfs(int stx,int sty,int edx,int edy){
	memset(vis,0,sizeof vis);
	queue<Node> q;
	Node cur,next;
	cur.x = stx;
	cur.y = sty;
	cur.step = 0;
	vis[cur.x][cur.y] = 1;
	q.push(cur);
	int ans;
	while(!q.empty()){
		cur = q.front();
		q.pop();
		if(cur.x == edx && cur.y == edy){
			ans = cur.step;
			break;
		}
		for(int i=0;i<4;i++){
			next = cur;
			next.x += dir[i][0];
			next.y += dir[i][1];
			next.step ++;
			if(!check(next.x,next.y)) continue;
			vis[next.x][next.y] = 1;
			q.push(next);
		}
	}
	return ans;
}
int main(){
	while(scanf("%d%d%d",&n,&m,&k)!=EOF){
		for(int i=0;i<n;i++)
			sfs(ch[i]);
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				if(ch[i][j] == 'S'){
					posx[0]=i;
					posy[0]=j;
				}
				if(ch[i][j]>='1' && ch[i][j]<='9'){
					posx[ch[i][j]-'0'] = i;
					posy[ch[i][j]-'0'] = j;
				}
			}
		}
		int ans=0;
		for(int i=0;i<k;i++){
			ans += bfs(posx[i],posy[i],posx[i+1],posy[i+1]);
		}
		printf("%d\n",ans);
	}
    return 0;
}