Problem:
チーズ (Cheese)
問題
今年も JOI 町のチーズ工場がチーズの生産を始め，ねずみが巣から顔を出した．JOI 町は東西南北に区画整理されていて，各区画は巣，チーズ工場，障害物，空き地のいずれかである．ねずみは巣から出発して全てのチーズ工場を訪れチーズを 1 個ずつ食べる．
この町には，N 個のチーズ工場があり，どの工場も１種類のチーズだけを生産している．チーズの硬さは工場によって異なっており，硬さ 1 から N までのチーズを生産するチーズ工場がちょうど 1 つずつある．
ねずみの最初の体力は 1 であり，チーズを 1 個食べるごとに体力が 1 増える．ただし，ねずみは自分の体力よりも硬いチーズを食べることはできない．
ねずみは，東西南北に隣り合う区画に 1 分で移動することができるが，障害物の区画には入ることができない．チーズ工場をチーズを食べずに通り過ぎることもできる．すべてのチーズを食べ終えるまでにかかる最短時間を求めるプログラムを書け．ただし，ねずみがチーズを食べるのにかかる時間は無視できる．
入力
入力は H+1 行ある．1 行目には 3 つの整数 H，W，N (1 ≤ H ≤ 1000，1 ≤ W ≤ 1000，1 ≤ N ≤ 9) がこの順に空白で区切られて書かれている．2 行目から H+1 行目までの各行には，'S'，'1', '2', ..., '9'，'X'，'.' からなる W 文字の文字列が書かれており，各々が各区画の状態を表している．北から i 番目，西から j 番目の区画を (i,j) と記述することにすると (1 ≤ i ≤ H, 1 ≤ j ≤ W)，第 i+1 行目の j 番目の文字は，区画 (i,j) が巣である場合は 'S' となり，障害物である場合は 'X' となり，空き地である場合は '.' となり，硬さ 1, 2, ..., 9 のチーズを生産する工場である場合はそれぞれ '1', '2', ..., '9' となる．入力には巣と硬さ 1, 2, ..., N のチーズを生産する工場がそれぞれ 1 つずつある．他のマスは障害物または空き地であることが保証されている．ねずみは全てのチーズを食べられることが保証されている．
出力
すべてのチーズを食べ終えるまでにかかる最短時間（分）を表す整数を 1 行で出力せよ．
入出力例
入力例 1
3 3 1
S..
...
..1
出力例 1
4
入力例 2
4 5 2
.X..1
....X
.XX.S
.2.X.
出力例 2
12
入力例 3
10 10 9
.X...X.S.X
6..5X..X1X
...XXXX..X
X..9X...X.
8.X2X..X3X
...XX.X4..
XX....7X..
X..X..XX..
X...X.XX..
..X.......
出力例 3
91
問題文と自動審判に使われるデータは、
情報オリンピック日本委員会
が作成し公開している問題文と採点用テストデータです。

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
int H, W, N;
char mp[1005][1005];
bool isvis[1005][1005];
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin>>H>>W>>N;
    int x = -1, y = -1;
    for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) {
            cin>>mp[i][j];
            if (mp[i][j] == 'S') {
                x = i;
                y = j;
            }
        }
    }
    int ans = 0;
    for (int i = 1; i <= N; i++) {
        queue<tuple<int,int,int>> q;
        memset(isvis,false,sizeof(isvis));
        q.emplace(x,y,ans);
        isvis[x][y] = true;
        while (!q.empty()) {
            int xx = get<0>(q.front());
            int yy = get<1>(q.front());
            int now = get<2>(q.front());
            q.pop();
            if (mp[xx][yy] - '0'== i) {
                ans = now;
                x = xx;
                y = yy;
                break;
            }
            for (int j = 0; j < 4; j++) {
                int nx = xx + dx[j];
                int ny = yy + dy[j];
                if (nx < 0 || ny < 0 || nx >= H || ny >= W || mp[nx][ny] == 'X' || isvis[nx][ny] == true) continue;
                isvis[nx][ny] = true;
                q.emplace(nx,ny,now+1);
            }
        }
    }
    cout<<ans<<"\n";
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 5504
final_rank: 1

code_snippet: #ifndef OMLINE_JUDGE
#define _GLGBCXX_DEBUG
#endif
#include <bits/stdc++.h>
using namespace std;

struct Rat_move
{
    int y;
    int x;
    int num;
    int dist;
};

vector<pair<int, int>> move_direction{
    {-1, 0}, // up
    {1, 0},  // down
    {0, -1}, // left
    {0, 1},  // right
};

int H, W, N, answer = 0;

bool is_in_table(int y, int x)
{
    if (y >= 0 && y < H && x >= 0 && x < W)
        return true;

    return false;
}

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

    vector<vector<string>> cheese_map(N, vector<string>(H));

    for (int i = 0; i < H; i++)
    {
        string row;
        cin >> row;

        for (int j = 0; j < N; j++)
            cheese_map.at(j).at(i) = row;
    }

    queue<Rat_move> Queue;

    for (int i = 0; i < H; i++)
    {
        for (int j = 0; j < W; j++)
        {
            if (cheese_map.at(0).at(i).at(j) == 'S')
            {
                cheese_map.at(0).at(i).at(j) = 'X';
                Queue.push(Rat_move{i, j, 0, 0});
            }
            else if (
                cheese_map.at(0).at(i).at(j) >= '1' &&
                cheese_map.at(0).at(i).at(j) <= static_cast<char>(N - 1 + '0'))
            {
                cheese_map.at(
                              static_cast<int>(cheese_map.at(0).at(i).at(j) - '0'))
                    .at(i)
                    .at(j) = 'X';
                Queue.push(
                    Rat_move{
                        i,
                        j,
                        static_cast<int>(cheese_map.at(0).at(i).at(j) - '0'),
                        0});
            }
        }
    }

    while (!Queue.empty())
    {
        auto pos = Queue.front();
        Queue.pop();

        for (int k = 0; k < 4; k++)
        {
            int nex_y = pos.y + move_direction.at(k).first,
                nex_x = pos.x + move_direction.at(k).second;

            if (
                is_in_table(nex_y, nex_x) &&
                cheese_map.at(pos.num).at(nex_y).at(nex_x) != 'X')
            {
                if (
                    cheese_map.at(pos.num).at(nex_y).at(nex_x) ==
                    static_cast<char>(pos.num + 1 + '0'))
                    answer += pos.dist + 1;
                else
                    Queue.push(Rat_move{nex_y, nex_x, pos.num, pos.dist + 1});

                cheese_map.at(pos.num).at(nex_y).at(nex_x) = 'X';
            }
        }
    }

    cout << answer << '\n';

    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 12616
final_rank: 16

code_snippet: #include<bits/stdc++.h>
using namespace std;
const int N = 1010;
struct node{
	int x,y,c;
};
int n,m,k,sx,sy,ans;
char a[N][N];
bool vis[N][N];
queue <node> q;
int dx[5]={0,1,0,-1};
int dy[5]={1,0,-1,0};
int bfs(int x,int y,int f){
	vis[x][y]=1;
	q.push((node){x,y,0});
	while(!q.empty()){
		node t=q.front();
		q.pop();
		if(a[t.x][t.y]==f+'0'){
			while(!q.empty()) q.pop();
			sx=t.x;
			sy=t.y;
			return t.c;
		}
		for(int i=0;i<4;i++){
			int zx=t.x+dx[i];
			int zy=t.y+dy[i];
			if(zx>=1&&zx<=n&&zy>=1&&zy<=m&&!vis[zx][zy]&&a[zx][zy]!='X'){
				vis[zx][zy]=1;
				q.push((node){zx,zy,t.c+1});
			}
		}
	}
	return 0;
}
int main(){
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>a[i][j];
			if(a[i][j]=='S'){
				sx=i;
				sy=j;
			}
		}
	}
	for(int i=1;i<=k;i++){
		ans+=bfs(sx,sy,i);
		for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) vis[i][j]=0;
	}
	cout<<ans<<'\n';
	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 5116
final_rank: 6

code_snippet: #include<iostream>
#include<queue>
using namespace std;
const int maxn=1000,mxw=10;
const int dx[]={1,0,0,-1},dy[]={0,1,-1,0};
int a[maxn][maxn],n,m,sx[mxw],sy[mxw]; 
bool check(int x,int y){
	return x>=0&&x<n&&y>=0&&y<m;
}
int bfs(int idx){
	queue<int>qx,qy;
	a[sx[idx]][sy[idx]]=idx;
	qx.push(sx[idx]),qy.push(sy[idx]);
	int cnt=1,tc,res=1;
	while(!qx.empty()){
		tc=0;
		while(cnt--){
			int x=qx.front(),y=qy.front();
			qx.pop(),qy.pop();
			for(int i=0,nx,ny;i<4;i++){
				nx=x+dx[i],ny=y+dy[i];
				if(nx==sx[idx+1]&&ny==sy[idx+1])return res;
				if(check(nx,ny)&&a[nx][ny]<idx){
					qx.push(nx),qy.push(ny);
					a[nx][ny]=idx,tc++;	
				}
			}
		}
		cnt=tc,res++;
	}
	return 0;
}
int main(){
	int w;
	cin>>n>>m>>w;
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++){
			char ch;
			cin>>ch;
			if(ch=='S')sx[0]=i,sy[0]=j;
			if(isdigit(ch)){
				int k=ch-'0';
				sx[k]=i,sy[k]=j;
			}
			if(ch=='X')a[i][j]=w+1;
			else a[i][j]=-1;
		}
	int ans=0;
	for(int i=0;i<w;i++){
		ans+=bfs(i);
	}
	cout<<ans<<endl;
 	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 7236
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include<utility>
#include<set>
#include<deque>
#include <unordered_map>
#include<string>
#include<cmath>

using namespace std;
int H, W, N;
pair<int, int>S;
int Y[4] = {0,0,1,-1};
int X[4] = {1,-1 ,0,0};
int bfs(int sy, int sx, char target, const vector<vector<char>>& M, int cost) {
	
	vector<vector<int>>Z(H, vector<int>(W, 0));
	deque<pair<int, int>>K;
	K.push_back({ sy,sx });
	Z[sy][sx] =1;
	while (K.empty() == false) {
		pair<int, int>P = K.front();
		sy = P.first;
		sx = P.second;
		K.pop_front();

		for (int i = 0; i < 4; i++) {
			int ny = sy + X[i];
			int nx = sx + Y[i];
			
			if (ny >= H or ny < 0 or nx >= W or nx < 0)continue;
			if (M[ny][nx] == 'X') {
				Z[ny][nx] = -1;
				continue;
			}
			if (M[ny][nx] == target) {
				S.first = ny;
				S.second = nx;
				int u = cost + Z[sy][sx];
				return u;
			}
			if (Z[ny][nx] == 0) {
				K.push_back({ ny,nx });
				Z[ny][nx] = Z[sy][sx] + 1;
			}






		}
	}
	return -1;
}


const int MOD = 100000;
int main() {
	
	cin >> H >> W >> N;
	vector<vector<char>>M(H, vector<char>(W));
	int ans = 0;
	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W; j++) {
			cin >> M[i][j];

			if (M[i][j] == 'S') {
				S.first = i;
				S.second = j;
			}
		}
	}

	
	for (int i = 1; i <= N; i++) {
		char target = '0' + i;
		ans=bfs(S.first, S.second, target, M, ans);
	}

	cout << ans<<endl;
}
accuracy: 1
time_ms: 50
memory_kb: 7936
final_rank: 10

code_snippet: #include<iostream>
#include<queue>
#include<utility>
#include<cstring>
#include<vector>
using namespace std;
typedef pair<int ,int> p;
const int N=1010; 
int tatol;
int H,W,n;
char a[N][N];
int sx,sy;
int ox,oy;
int dx[]={-1,0,1,0},dy[]={0,1,0,-1};
int dist[N][N];
vector<p> ch(10);
int  bfs(int x,int y,int ox,int oy){
	queue<p> q;
	q.push({x,y});
	memset(dist,-1,sizeof dist);
	dist[x][y]=0;
	while(!q.empty()){
		p t=q.front();
		q.pop();
		if(t.first==ox&&t.second==oy) return dist[ox][oy];
		for(int i=0;i<4;i++){
			int ax=t.first+dx[i],ay=t.second+dy[i];
			if(ax>=0&&ay>=0&&ax<H&&ay<W){
				if(a[ax][ay]!='X'&&dist[ax][ay]==-1){
					dist[ax][ay]=dist[t.first][t.second]+1;
					q.push({ax,ay});
				}
			}
		}
	}
	return -1;
}
int main(){
	cin>>H>>W>>n;
	for(int i=0;i<H;i++){
		for(int j=0;j<W;j++){
			cin>>a[i][j];
			if(a[i][j]=='S') sx=i,sy=j;
			if(isdigit(a[i][j])){
				int digit=a[i][j]-'0';
				ch[digit]={i,j};
			}
		}
	}
	for(int i=1;i<=n;i++){
		p t=ch[i];
		ox=t.first,oy=t.second;
		tatol+=bfs(sx,sy,ox,oy);
		sx=ox,sy=oy;
	}
	cout<<tatol<<endl;
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 8268
final_rank: 8

code_snippet: #include <iostream>
#include <sstream>
#include <queue>
#include <cstring>

int targetX[10];
int targetY[10];
char grid[1000][1000];
bool visited[1000][1000];
int H, W, N;

struct Point {
    int x;
    int y;
    int dist;
};

int dist(int x1, int y1, int x2, int y2) {
    int dist = 0;
    std::queue<Point> q;
    q.push({x1, y1, 0});
    while (!q.empty()) {
        Point p = q.front();
        q.pop();
        if (p.x == x2 && p.y == y2) {
            return p.dist;
        }
        if (visited[p.x][p.y]) {
            continue;
        }
        visited[p.x][p.y] = true;
        int dx[] = {0, 0, -1, 1};
        int dy[] = {-1, 1, 0, 0};
        for (int i = 0; i < 4; i++) {
            if (p.x + dx[i] < 0 || p.x + dx[i] >= H || p.y + dy[i] < 0 || p.y + dy[i] >= W 
                || visited[p.x + dx[i]][p.y + dy[i]] || grid[p.x + dx[i]][p.y + dy[i]] == 'X') {
                continue;
            }
            q.push({p.x + dx[i], p.y + dy[i], p.dist + 1});
        }
    }
    return 0;
}

int main() {
    std::string line;
    std::getline(std::cin, line);
    
    std::istringstream iss(line);
    iss >> H >> W >> N;
    
    for (int i = 0; i < H; i++) {
        std::getline(std::cin, line);
        for (int j = 0; j < W; j++) {
            char c = line[j];
            switch (c) {
                case 'S':
                    targetX[0] = i;
                    targetY[0] = j;
                    grid[i][j] = '.';
                    break;
                case 'X':
                    grid[i][j] = 'X';
                    break;
                case '.':
                    grid[i][j] = '.';
                    break;
                default:
                    if (c >= '1' && c <= '9') {
                        int idx = (c - '0');
                        targetX[idx] = i;
                        targetY[idx] = j;
                        grid[i][j] = '.';
                    }
                    break;
            }
        }
    }
    
    int result = 0;
    for (int i = 0; i < N; i++) {
        std::memset(visited, 0, sizeof(visited));
        result += dist(targetX[i], targetY[i], targetX[i + 1], targetY[i + 1]);
    }
    std::cout << result << std::endl;
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 5160
final_rank: 2

code_snippet: #include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<cstring>
#include<queue>
using namespace std;
const int INF = 10000;
char map[INF][INF];
int n, m;
int beginx, beginy,endx,endy;
int dx[4] = { 0,1,0,-1 };
int dy[4] = { 1,0,-1,0 };
int d[INF][INF];
int mincount;
int min;
typedef pair<int, int>q;
int  bfs(int ax, int ay,int bx,int by)
{
	queue<q>que;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)
			d[i][j] = INF;
	que.push(q(ax, ay));
	d[ax][ay] = 0;
	while (que.size())
	{
		q s = que.front();
		que.pop();
		if (s.first == bx && s.second == by)
			return d[bx][by];
		for (int i = 0; i < 4; i++)
		{
			int nx = s.first + dx[i];
			int ny = s.second + dy[i];
			if (nx >= 0 && nx < n && ny >= 0 && ny < m && map[nx][ny] != 'X' && d[nx][ny] == INF)
			{
				que.push(q(nx, ny));
				d[nx][ny] = d[s.first][s.second] + 1;
			}

		}

	}
	return -1;
}

int main()
{
	int x;
	cin >> n >> m >> x;
	int min = 0;
	int treex[10];
	int treey[10];
	int count1 = 1;
	vector<q>tree(x + 1);
	int countsum = 0, sum = 0;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)
		{
			cin >> map[i][j];
			if (map[i][j] == 'S')
			{
				beginx = i;
				beginy = j;
				map[i][j] = '.';
			}
			if (map[i][j] <= '9' && map[i][j] >= '1')
			{
				int count = map[i][j] - '0';
				tree[count] = q(i, j);
				
			}
		}
	int tonx, tony;
	for (int i = 1; i <= x; i++)
	{
		int xx = tree[i].first;
		int yy = tree[i].second;
	
		if (i == 1)
		{
			countsum = bfs(beginx, beginy, xx, yy);
			tonx = xx;
			tony = yy;
			sum += countsum;
		}
		else
		{
			countsum = bfs(tonx, tony, xx, yy);
			sum += countsum;
			tonx = xx;
			tony = yy;
		}
	}
	cout << sum  << endl;
	
}
accuracy: 1
time_ms: 50
memory_kb: 54908
final_rank: 18

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

#define MAXN 10000

using namespace std;

typedef pair<int, int> P;

int H, W, N;
int sx, sy;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
int d[MAXN][MAXN];
char field[MAXN][MAXN];


int bfs(int x, int y, char target) {
    for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) {
            d[i][j] = MAXN;
        }
    }

    d[x][y] = 0;
    int gx, gy;
    queue<P> que; que.push(P(x, y));
    while (que.size()) {
        P p = que.front(); que.pop();
        if (field[p.first][p.second] == target) {
            gx = p.first; gy = p.second;
            break;
        }

        for (int i = 0; i < 4; i++) {
            int nx = p.first + dx[i];
            int ny = p.second + dy[i];
            if (0 <= nx && nx < H && 0 <= ny && ny < W && field[nx][ny] != 'X' && d[nx][ny] == MAXN) {
                d[nx][ny] = d[p.first][p.second] + 1;
                P newp = {nx, ny};
                que.push(newp);
            }
        }
    }

    sx = gx; sy = gy;
    return d[gx][gy];
}

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

    cin >> H >> W >> N;
    for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) {
            cin >> field[i][j];
            if (field[i][j] == 'S') {
                sx = i; sy = j;
            }
        }
    }

    int step = 0;
    for (int i = 1; i <= N; i++) {
        step += bfs(sx, sy, i + '0');
    }

    cout << step << '\n';
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 53452
final_rank: 17

code_snippet: #include <iostream>
#include <queue>
using namespace std;
const int MAX_H = 1050;
const int MAX_W = 1050;
const int INF = 1e8;
char map[MAX_H][MAX_W];
int w, h, n;
int spx, spy;
int gpx, gpy;
int step = 0;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
typedef pair<int, int> P;
int d[MAX_H][MAX_W];

int bfs(int strength)
{
    queue<P> q;
    P p;
    for (int i = 0; i < h; ++i)
    {
        for (int j = 0; j < w; ++j)
        {
            d[i][j] = INF;
        }
    }

    q.push(P(spx, spy));
    d[spx][spy] = 0;

    while (q.size())
    {
        p = q.front();
        q.pop();

        if (map[p.first][p.second] - '0' == strength)
        {
            spx = p.first;
            spy = p.second;
            break;
        }

        // 四个方向循环
        for (int i = 0; i < 4; ++i)
        {
            int nx = p.first + dx[i];
            int ny = p.second + dy[i];

            if ((map[nx][ny] != 'X' || (map[nx][ny] - '0') <= strength) && 0 <= nx && nx < h && 0 <= ny && ny < w && d[nx][ny] == INF)
            {
                q.push(P(nx, ny));
                d[nx][ny] = d[p.first][p.second] + 1;
            }
        }
    }
    return d[spx][spy];
}

void solve()
{
    step = 0;
    for (int i = 1; i <= n; ++i)
    {
        step += bfs(i);
    }
}

int main()
{
    cin >> h >> w >> n;
    for (int i = 0; i < h; ++i)
    {
        for (int j = 0; j < w; ++j)
        {
            cin >> map[i][j];
            if (map[i][j] == 'S')
            {
                spx = i;
                spy = j;
            }
        }
    }

    solve();

    cout << step << endl;
}
accuracy: 1
time_ms: 50
memory_kb: 8508
final_rank: 12

code_snippet: #include <iostream>
#include <queue>
using namespace std;
const int MAX_H = 1000;
const int MAX_W = 1000;
const int INF = 1e8;
char map[MAX_H][MAX_W];
int w, h, n;
int spx, spy;
int gpx, gpy;
int step = 0;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
typedef pair<int, int> P;
int d[MAX_H][MAX_W];

int bfs(int strength)
{
    queue<P> q;
    P p;
    for (int i = 0; i < h; ++i)
    {
        for (int j = 0; j < w; ++j)
        {
            d[i][j] = INF;
        }
    }

    q.push(P(spx, spy));
    d[spx][spy] = 0;

    while (q.size())
    {
        p = q.front();
        q.pop();

        if (map[p.first][p.second] - '0' == strength)
        {
            spx = p.first;
            spy = p.second;
            break;
        }

        // 四个方向循环
        for (int i = 0; i < 4; ++i)
        {
            int nx = p.first + dx[i];
            int ny = p.second + dy[i];

            if ((map[nx][ny] != 'X' || (map[nx][ny] - '0') <= strength) && 0 <= nx && nx < h && 0 <= ny && ny < w && d[nx][ny] == INF)
            {
                q.push(P(nx, ny));
                d[nx][ny] = d[p.first][p.second] + 1;
            }
        }
    }
    return d[spx][spy];
}

void solve()
{
    step = 0;
    for (int i = 1; i <= n; ++i)
    {
        step += bfs(i);
    }
}

int main()
{
    cin >> h >> w >> n;
    for (int i = 0; i < h; ++i)
    {
        for (int j = 0; j < w; ++j)
        {
            cin >> map[i][j];
            if (map[i][j] == 'S')
            {
                spx = i;
                spy = j;
            }
        }
    }

    solve();

    cout << step << endl;
}
accuracy: 0.8
time_ms: 50
memory_kb: 7996
final_rank: 20

code_snippet: #include<string>
#include<iostream>
#include<queue>
#include<bits/stdc++.h>
using namespace std;
int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
struct board {
    string bd[1024];
    pair<int,int> cpos[20];
    int h, w, ch;
    pair<int,int> st;
    void read() {
        cin >> h >> w >> ch;
        for(int i = 0; i < h; i++) {
            cin >> bd[i];
        }
        for(int i = 0; i < h; i++) {
            for(int j = 0; j < w; j++) {
                if(isdigit(bd[i][j])) {
                    cpos[bd[i][j]-'0'] = {i, j};
                } else if(bd[i][j] == 'S') {
                    st = {i, j};
                }
            }
        }
    }
    bool in_bd(int x, int y) {
        return x >= 0 && x < h && y >= 0 && y < w;
    }
    bool is_block(int x, int y) {
        return bd[x][y] == 'X';
    }
    int visited[1024][1024];
    int bfs(pair<int,int> from, pair<int,int> to) {
        memset(visited, -1, sizeof(visited));
        queue<pair<int,int>> q;q.push(from);visited[from.first][from.second]=0;
        //while(!)
        while(visited[to.first][to.second] == -1) {
            auto f = q.front(); q.pop();
            for(const auto& d: dir) {
                int nx = f.first+d[0], ny = f.second+d[1];
                if(!in_bd(nx, ny) || is_block(nx, ny)) {
                    continue;
                }
                if(visited[nx][ny] == -1) {
                    visited[nx][ny] = visited[f.first][f.second]+1;
                    q.push({nx, ny});
                }
            }
        }
        return visited[to.first][to.second];
    }
    void solve() {
        read();
        int ans = bfs(st, cpos[1]);
        for(int i = 1; i < ch; i++) {
            ans += bfs(cpos[i], cpos[i+1]);
        }
        cout << ans << endl;
    }
};
void solve() {
    board bd;
    bd.solve();
}
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    solve();
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 8448
final_rank: 4

code_snippet: //从起点按1到n顺序走完所有的奶酪场即可，从i到i+1个需要bfs 
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int dx[4]={-1,1,0,0};
const int dy[4]={0,0,-1,1};
struct node{
	int x,y,dep;
};
node q[1001*1001];
int a[1001][1001];
int vis[1001][1001];
int x[10],y[10];
int h,w,n;
int bfs(int k){
	memset(vis,0,sizeof(vis));
	int head=0,tail=1;
	q[0].x=x[k];q[0].y=y[k];q[0].dep=0;
	vis[x[k]][y[k]]=1;
	while(head<tail){
		node p=q[head++];
		int x0=p.x,y0=p.y,d=p.dep;
		if(x0==x[k+1]&&y0==y[k+1])return d;
		for(int i=0;i<4;i++){
			int xx=x0+dx[i],yy=y0+dy[i];
			if(xx>=1&&xx<=h&&yy>=1&&yy<=w&&a[xx][yy]==0&&vis[xx][yy]==0){
				q[tail++]=(node){xx,yy,d+1};
				vis[xx][yy]=1;
			}
		}
	}
return 0;
}
int main(){
	cin>>h>>w>>n;
	for(int i=1;i<=h;i++)
		for(int j=1;j<=w;j++){
			char ch;
			cin>>ch;
			a[i][j]=0;
			if(ch=='X')a[i][j]=1;
			if(ch=='S')x[0]=i,y[0]=j;
			if(ch>='1'&&ch<='9')x[ch-48]=i,y[ch-48]=j;
		}
	int ans=0;
	for(int i=0;i<n;i++)ans+=bfs(i);
	cout<<ans<<endl;
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 17664
final_rank: 15

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

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

int H, W, N;
vector<vector<char>> board;
vector<vector<int>> dist;
vector<int> x(10), y(10);

int bfs(int sx, int sy, int tx, int ty) {
    dist.assign(H, vector<int>(W, INF));
    dist[sx][sy] = 0;

    queue<pair<int, int>> que;
    que.push({sx, sy});

    while (!que.empty()) {
        auto [cx, cy] = que.front();
        que.pop();

        for (int k = 0; k < 4; ++k) {
            int nx = cx + dx[k], ny = cy + dy[k];
            if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;
            if (board[nx][ny] == 'X') continue;
            if (dist[nx][ny] > dist[cx][cy] + 1) {
                dist[nx][ny] = dist[cx][cy] + 1;
                que.push({nx, ny});
            }
        }
    }

    return dist[tx][ty];
}

int main() {
    cin >> H >> W >> N;
    board.resize(H, vector<char>(W));
    dist.resize(H, vector<int>(W));

    for (int i = 0; i < H; ++i) {
        for (int j = 0; j < W; ++j) {
            cin >> board[i][j];
            if (board[i][j] == 'S') board[i][j] = '0';
            if (isdigit(board[i][j])) {
                int val = board[i][j] - '0';
                x[val] = i;
                y[val] = j;
            }
        }
    }

    int ans = 0;
    for (int i = 0; i < N; ++i) {
        ans += bfs(x[i], y[i], x[i+1], y[i+1]);
    }

    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 8176
final_rank: 14

code_snippet: #include<bits/stdc++.h>
#pragma GCC optimize(2)
#define R(n) cin >> n
#define fr(i, a, b) for (int i = a; i <= b; i++)
#define rf(i, a, b) for (int i = a; i >= b; i--)
#define L long long
#define I int
#define E return
#define B break
#define C continue
#define W while
const I mod = 998244353;
using namespace std;
I n,m,k;
char mp[1005][1005];
I x[1005],y[1005],s,ss;
I vis[1005][1005];
queue<pair<I,pair<I,I> > >q;
bool ivl(I x,I y){
	if(x<1||y<1||x>n||y>m)
		E 1;
	if(mp[x][y]=='X')
	E 1;
	if(vis[x][y])
	E 1;
	E 0;
}
void ini(){
	W(!q.empty())q.pop();
	memset(vis,0,sizeof vis);
}
int bfs(int xs, int ys, int xe, int ye){
	q.push(make_pair(0,make_pair(xs,ys)));
	I dx[]={0,1,-1,0,0},dy[]={0,0,0,1,-1};
	vis[xs][ys]=1;
	W(!q.empty()){
		I dep=q.front().first,nx=q.front().second.first,ny=q.front().second.second;
		q.pop();
		fr(i,1,4){
			I gx=nx+dx[i],gy=ny+dy[i];
			if(gx==xe&&gy==ye)
				E dep+1;
			if(!ivl(gx,gy)){
				vis[gx][gy]=1;
				q.push(make_pair(dep+1,make_pair(gx,gy)));
			}
		}
	}
	E -1;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	R(n)>>m>>k;
	fr(i,1,n)
		fr(j,1,m){
			R(mp[i][j]);
				if(mp[i][j]>=48&&mp[i][j]<=57)
					x[mp[i][j]-48]=i,y[mp[i][j]-48]=j;
				if(mp[i][j]=='S')
					s=i,ss=j;
			}
	ini();
	I ans=bfs(s,ss,x[1],y[1]);
	fr(i,1,k-1){ini();
	ans+=bfs(x[i],y[i],x[i+1],y[i+1]);}
	cout<<ans<<"\n";
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 8200
final_rank: 7

code_snippet: #include <cstdio>
#include <queue>
#include <unordered_set>
#include <utility>

int H, W, N;

char G[1000][1000];

struct state {
  int i, j, ct;
};

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

struct pair_hash {
  inline std::size_t operator()(const std::pair<int, int> &v) const {
    return v.first * 1050 + v.second;
  }
};

state bfs(state st, char target) {
  std::queue<state> q;

  q.push(st);

  std::unordered_set<std::pair<int, int>, pair_hash> seen;

  while (!q.empty()) {
    auto st = q.front();
    q.pop();

    if (G[st.i][st.j] == target) {
      return st;
    }

    if (auto it = seen.find({st.i, st.j}); it != seen.end()) {
      continue;
    }

    seen.insert({st.i, st.j});

    for (int i = 0; i < 4; i++) {
      int ni = st.i + dir[i][0], nj = st.j + dir[i][1];
      if (ni >= 0 && ni < H && nj >= 0 && nj < W && G[ni][nj] != 'X') {
        q.push({ni, nj, st.ct + 1});
      }
    }
  }

  return st;
}

int main() {
  scanf("%d %d %d", &H, &W, &N);
  state st;
  for (int i = 0; i < H; i++) {
    char s[1000];
    for (int j = 0; j < W; j++) {
      scanf(" %c", &G[i][j]);
      if (G[i][j] == 'S') {
        st = {i, j, 0};
      }
    }
  }

  for (int i = 1; i <= N; i++) {
    st = bfs(st, '0' + i);
  }

  printf("%d\n", st.ct);

  return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 27676
final_rank: 19

code_snippet: #include <iostream>
#include <queue>
#include <vector>
#include <climits>
#include <algorithm>

using namespace std;

// 東西南北の移動方向
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};

int h, w, n;  // 高さ、幅、チーズの数
vector<string> grid;  // 町の地図

// BFSを用いて最短経路を求める
int bfs(int sx, int sy, int ex, int ey) {
    vector<vector<int>> dist(h, vector<int>(w, INT_MAX));
    queue<pair<int, int>> q;
    dist[sx][sy] = 0;
    q.push({sx, sy});
    
    while (!q.empty()) {
        int x = q.front().first;
        int y = q.front().second;
        q.pop();
        
        for (int i = 0; i < 4; i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];
            
            if (nx >= 0 && nx < h && ny >= 0 && ny < w && grid[nx][ny] != 'X' && dist[nx][ny] == INT_MAX) {
                dist[nx][ny] = dist[x][y] + 1;
                q.push({nx, ny});
            }
        }
    }
    
    return dist[ex][ey];
}

int main() {
    cin >> h >> w >> n;
    
    grid.resize(h);
    pair<int, int> start;  // 巣の位置
    vector<pair<int, int>> cheese_positions(n);  // 各チーズ工場の位置
    
    // 地図の入力
    for (int i = 0; i < h; i++) {
        cin >> grid[i];
        for (int j = 0; j < w; j++) {
            if (grid[i][j] == 'S') {
                start = {i, j};  // 巣の位置
            }
            if (grid[i][j] >= '1' && grid[i][j] <= '9') {
                cheese_positions[grid[i][j] - '1'] = {i, j};  // チーズ工場の位置
            }
        }
    }
    
    // ねずみの移動時間の合計
    int total_time = 0;
    pair<int, int> current_pos = start;
    
    // チーズを硬さ順に訪れる
    for (int i = 0; i < n; i++) {
        pair<int, int> next_pos = cheese_positions[i];
        total_time += bfs(current_pos.first, current_pos.second, next_pos.first, next_pos.second);
        current_pos = next_pos;
    }
    
    cout << total_time << endl;
    
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 8860
final_rank: 13

code_snippet: #include<iostream>
#include<map>
#include<queue>
#include<cstring>
using namespace std;
int h,w,n;
const int N=1000+5,M=15,INF=0x3f3f3f3f;
char g[N][N];
int dist[N][N];
int idx[M],idy[M];
typedef pair<int,int> P;
int dx[]={0,1,0,-1},//
	dy[]={1,0,-1,0}; 
int bfs(int i)
{
	queue<P> q;//
	q.push(P{idx[i],idy[i]});
	memset(dist,0x3f,sizeof dist);
	dist[idx[i]][idy[i]]=0;
	while(!q.empty())
	{
		P cur=q.front(); q.pop();
		int x=cur.first,y=cur.second;
		if(x==idx[i+1]&&y==idy[i+1])
			return dist[x][y];
		for(int j=0;j<4;++j)
		{
			int nx=x+dx[j],ny=y+dy[j];
			if(dist[nx][ny]==INF&&g[nx][ny]!='X'&&nx>=1&&nx<=h&&ny>=1&&ny<=w)
			{
				q.push(P{nx,ny});
//				cout<<nx<<' '<<ny<<endl;;
				dist[nx][ny]=dist[x][y]+1;
			}
		}
	}
	return -1;
}
int main()
{
	cin>>h>>w>>n;
	for(int i=1;i<=h;++i)
		for(int j=1;j<=w;++j)
		{
			cin>>g[i][j];
			if(g[i][j]>'0'&&g[i][j]<='9')
			{
				int cur=g[i][j]-'0';
				idx[cur]=i;
				idy[cur]=j;
			}
			else if(g[i][j]=='S')
			{
				idx[0]=i;
				idy[0]=j;
			}
		}
	int sum=0;
	for(int i=0;i<n;++i)
	{
		sum+=bfs(i);
	} 
	cout<<sum<<endl;
	
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 8272
final_rank: 9

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

const int INF = 9999999;
int d[1010][1010], H, W, N, flag[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
typedef pair<int, int> P;
P che[11], S;
char m[1010][1010];
void solve() {}
int bfs(P s, P g) {
  fill(d[0], d[0] + 1010 * 1010, INF);
  queue<P> que;
  P p;
  que.push(s);
  d[s.first][s.second] = 0;
  while (que.size()) {
    p = que.front();
    que.pop();
    if (p == g)
      break;
    for (int i = 0; i < 4; ++i) {
      int nx = p.first + flag[i][0], ny = p.second + flag[i][1];
      if (nx >= 0 && nx < H && ny >= 0 && ny < W && m[nx][ny] != 'X' && d[nx][ny] == INF) {
        d[nx][ny] = d[p.first][p.second] + 1;
        que.push(P(nx, ny));
      }
    }
  }
  return d[g.first][g.second];
}
int main() {
  //freopen("aizu0558.in", "r", stdin);
  int ans = 0;
  scanf("%d %d %d", &H, &W, &N);
  getchar();
  for (int i = 0; i < H; ++i) {
    for (int j = 0; j < W; ++j) {
      m[i][j] = getchar();
      if (m[i][j] >= '1' && m[i][j] <= '9')
        che[m[i][j] - '0'].first = i, che[m[i][j] - '0'].second = j;
      else if (m[i][j] == 'S')
        che[0].first = i, che[0].second = j;
    }
    getchar();
  }
  for(int i = 0 ; i < N; ++i)
    ans += bfs(che[i], che[i+1]);
  printf("%d\n", ans);
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 7700
final_rank: 3

code_snippet: #include<iostream>
#include<queue>
#include<cstring>
#define MEM(x, y) memset(x, y, sizeof x)
#define MAXN 1005

using namespace std;
typedef pair<int, int> PII;
int dx[4] = { -1, 0, 1, 0};
int dy[4] = { 0, 1, 0, -1};

char maze[MAXN][MAXN];
int step[MAXN][MAXN];
int sx, sy, gx, gy;
int h, w, n;
int ans = 0;

void bfs(int sx, int sy){
	queue<PII>que;
	que.push(PII(sx, sy));
	step[sx][sy] = 0;
	while(!que.empty()){
		PII p = que.front(); que.pop();
		for(int i = 0; i < 4; i++){
			int nx = p.first + dx[i], ny = p.second + dy[i];
			if(nx > 0 && ny > 0 && nx <= h && ny <= w && maze[nx][ny] != 'X' && step[nx][ny] == -1){
				step[nx][ny] = 1 + step[p.first][p.second];
				que.push(PII(nx, ny));
			}
		}
	}
}
int main(){
	cin>>h>>w>>n;
	PII pii[10];
	for(int i = 1; i <= h; i++){
		for(int j = 1; j <= w; j++){
			cin>>maze[i][j];
			if(maze[i][j] <= '9' && maze[i][j] >= '1'){
				pii[maze[i][j] - '0'] = PII(i, j);
			}
			else if(maze[i][j] == 'S'){
				pii[0] = PII(i, j);
				maze[i][j] = '.';
			}
		}
	}
	for(int i = 1; i <= n; i++){
		MEM(step, -1);
		sx = pii[i - 1].first, sy = pii[i - 1].second;
		gx = pii[i].first, gy = pii[i].second;
		//cout<<gx<<" "<<gy<<endl;
		bfs(sx, sy);
		ans += step[gx][gy];
	}
	cout<<ans<<endl;
	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 8240
final_rank: 11