Problem:
カーペット (Carpet)
問題文
オシャレ好きのビ太郎は，カーペットを新調した．カーペットは縦
H
行，横
W
列のマス目状に区切られた長方形の形をしており，各マスは白か黒のいずれかの色で塗られている．カーペットの上から
i
行目，左から
j
列目 (
1 ≦ i ≦ H
，
1 ≦ j ≦ W
) にあるマスの色は，文字列
S
i
の
j
文字目が
.
のとき白色，
#
のとき黒色である．
ビ太郎は，カーペットの最も左上のマスに駒を置き，以下の操作を何回か行うことで，その駒をカーペットの最も右下のマスに到達させるという遊びを思いついた．
駒が置かれているマスと色が異なり，かつ上下左右に隣接するマスを
1
つ選び，そのマスに駒を移動させる．
ビ太郎は，到達までの操作回数をなるべく少なくしたい．ただし，カーペットの模様によっては到達させられないかもしれない．
カーペットの模様の情報が与えられたとき，操作を繰り返すことで左上のマスから右下のマスに駒を到達させることが可能かを判定し，可能ならば操作回数の最小値を求めるプログラムを作成せよ．
制約
1 ≦ H ≦ 500
．
1 ≦ W ≦ 500
．
(H, W) ≠ (1, 1)
．
S
i
は長さ
W
の文字列である (
1 ≦ i ≦ H
)．
S
i
の 各文字は
.
または
#
である (
1 ≦ i ≦ H
)．
H, W
は整数である．
入力
入力は以下の形式で標準入力から与えられる．
H
W
S
1
S
2
:
S
H
出力
操作を繰り返すことで左上のマスから右下のマスに駒を到達させることが可能な場合は操作回数の最小値を，不可能な場合は
-1
を，標準出力に
1
行で出力せよ．
入出力例
入力例 1
4 5
...#.
#####
...#.
#.###
出力例 1
9
例えば，図のような操作が考えられる．
左の例では
9
回の操作で，右の例では
13
回の操作で，左上のマスから右下のマスに駒を到達させることが可能である．
9
回よりも少ない操作回数で到達させることは不可能なので，
9
を出力する．
入力例 2
3 3
...
...
...
出力例 2
-1
はじめから操作ができない場合もある．この場合，駒を右下のマスに到達させることは不可能なので，
-1
を出力する．
入力例 3
1 5
.#.#.
出力例 3
4
入力例 4
5 5
###.#
.#...
.#..#
.####
##..#
出力例 4
12
入力例 5
7 5
.#.##
##...
.#.##
.###.
##.#.
...#.
##.#.
出力例 5
12
情報オリンピック日本委員会
作 『第 21 回日本情報オリンピック JOI 2021/2022 二次予選競技課題』

Submitted solutions:

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

using namespace std;


const int MOD = 10000;
int H, W;
int Y[4] = { 0,0,1,-1 };
int X[4] = { 1,-1 ,0,0 };

int bfs(int sy, int sx, int gy,int gx,const vector<vector<char>>& M) {
	//syはスタートのy座標
	//sxはスタートのy座標
	
	//targetはゴール（Gとか）
	vector<vector<int>>Z(H, vector<int>(W, 1e9));
	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];
			char F = M[sy][sx];
			if (ny >= H or ny < 0 or nx >= W or nx < 0) { continue; }
			if (M[ny][nx] == F) {
				continue;
			}

			if (ny==gy and nx==gx) {
				
				Z[ny][nx] = Z[sy][sx] + 1;
				return Z[ny][nx]-1;
			}
			if (Z[ny][nx] > Z[sy][sx] + 1) {
				K.push_back({ ny,nx });
				Z[ny][nx] = Z[sy][sx] + 1;
			}
			
		}
	}
	
	return -1;
}

int main() {
	
	cin >> H>>W;
	vector<vector<char>>M(H, vector<char>(W));

	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W; j++) {
			cin >> M[i][j];
		}
	}
	int h, w;
	h = H - 1;
	w = W - 1;
	int ans;
	ans=bfs(0, 0, h,w,  M);

	cout << ans<<endl;
}
accuracy: 1
time_ms: 10
memory_kb: 4528
final_rank: 2

code_snippet: #include "bits/stdc++.h"

#define REP(i,num) for(ll i=0;i<(num);++i)
#define FOR(i,c,num) for(ll (i)=(c);(i)<(num);++(i))
#define LOOP(i) while(i--)
#define ALL(c) c.begin(),c.end()
#define PRINTALL(c) for(auto pitr=c.begin();pitr!=c.end();++pitr){cout<<*pitr;if(next(pitr,1)!=c.end())cout<<' ';}cout<<endl;
#define PAIRCOMP(c,comp) [](const pair<ll,ll>& lhs,const pair<ll,ll>& rhs){return lhs.c comp rhs.c;}

using namespace std;
using ll = long long;
using ull = unsigned long long;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;

constexpr ll atcoder_mod = 1e9+7;

template<typename T=ll>
T in(){ T x; cin >> x; return (x); }
template<typename T=ll,typename C=vector<T>>
C vecin(int N){ C x(N);REP(i,N){ x[i]=in<T>(); }return x; }
template<typename T=ll,size_t N>
array<T,N> arrin(){array<T,N> x;REP(i,N){ x[i]=in<T>(); }return x;}

void vout(){ cout << endl; }
template<typename Head,typename... Tail>
void vout(Head&& h,Tail&&... t){ cout << ' ' << h;vout(forward<Tail>(t)...); }
void out(){ cout << endl; }
template<typename Head,typename... Tail>
void out(Head&& h,Tail&&... t){ cout << h;vout(forward<Tail>(t)...); }

template<typename T>
bool chmax(T& a,T b){ if(a<b){ a=b;return true; }return false; }
template<typename T>
bool chmin(T& a,T b){ if(a>b){ a=b;return true; }return false; }

class ConnectNodeInfo{
	vector<vector<pair<ll,ll>>> graph;
public:
	ConnectNodeInfo(int node_num){
		graph.resize(node_num);
	}
	void AddNonDirectionalConnection(ll u,ll v,ll w){
		graph[u].emplace_back(v,w);
		graph[v].emplace_back(u,w);
	}
	void AddDirectionalConnection(ll u,ll v,ll w){
		graph[u].emplace_back(v,w);
	}
	vector<pair<ll,ll>>& operator[](ll index){
		return graph[index];
	}
	size_t size(){ return graph.size(); }
};

class Dijkstra{
	using Point = pair<ll,ll>;
	vector<ll> dist;
public:
	void CalcShortestPath(int start,ConnectNodeInfo& connect){
		dist.resize(connect.size(),1LL<<60);
		dist[start] = 0;

		priority_queue<Point,vector<Point>,greater<Point>> Q;
		Q.emplace(0,start);
		while(!Q.empty()){
			auto p = Q.top();
			Q.pop();
			int v = p.second;
			if(dist[v]<p.first){
				continue;
			}
			for(auto e:connect[v]){
				if(dist[e.first]>dist[v]+e.second){
					dist[e.first] = dist[v]+e.second;
					Q.emplace(dist[e.first],e.first);
				}
			}
		}
	}
	ll GetDistance(int i){
		return dist[i];
	}
};

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	auto H=in(),W=in();
	ConnectNodeInfo connect(H*W);
	vector<string> M(H);
	REP(i,H) M[i]=in<string>();
	REP(i,H){
		REP(j,W){
			if(j<W-1 && M[i][j]!=M[i][j+1]){
				connect.AddNonDirectionalConnection(j+i*W,j+1+i*W,1);
			}
			if(i<H-1 && M[i][j]!=M[i+1][j]){
				connect.AddNonDirectionalConnection(j+i*W,j+(i+1)*W,1);
			}
		}
	}
	Dijkstra dij;
	dij.CalcShortestPath(0,connect);
	auto D=dij.GetDistance(H*W-1);
	out(D>=(1ll<<60)?-1:D);
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 30556
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define chmin(x,y) x = min(x,y)
#define chmax(x,y) x = max(x,y)
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001



#define SIZE 505

struct Info{
	Info(int arg_row,int arg_col,int arg_count){
		row = arg_row;
		col = arg_col;
		count = arg_count;
	}
	Info(){

		row = col = count = 0;
	}
	bool operator<(const struct Info& arg) const{

		return count > arg.count; //countの昇順(PQ)
	}
	int row,col,count;
};

int H,W;
int min_dist[SIZE][SIZE];
int d_row[4] = {-1,0,0,1},d_col[4] = {0,-1,1,0};
char buf[SIZE][SIZE];

bool rangeCheck(int row,int col){

	return row >= 0 && row <= H-1 && col >= 0 && col <= W-1;
}


int main(){

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

	for(int row = 0; row < H; row++){

		scanf("%s",buf[row]);
	}
	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){

			min_dist[row][col] = BIG_NUM;
		}
	}

	min_dist[0][0] = 0;
	priority_queue<Info> Q;
	Q.push(Info(0,0,0));

	while(!Q.empty()){

		Info info = Q.top();
		Q.pop();

		if(info.count > min_dist[info.row][info.col])continue;

		if(info.row == H-1 && info.col == W-1){

			printf("%d\n",info.count);
			return 0;
		}

		for(int i = 0; i < 4; i++){

			int adj_row = info.row+d_row[i];
			int adj_col = info.col+d_col[i];
			if(!rangeCheck(adj_row,adj_col)||buf[info.row][info.col] == buf[adj_row][adj_col])continue;

			int next_count = info.count+1;
			if(min_dist[adj_row][adj_col] > next_count){

				min_dist[adj_row][adj_col] = next_count;
				Q.push(Info(adj_row,adj_col,next_count));
			}
		}

	}

	printf("-1\n");

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