Language: C++

#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


enum DIR{
	North,
	East,
	South,
	West,
};

struct Node{
	int num,parent_id,children[4],suffix_link,depth;
	bool finish_FLG;
	DIR pattern[10];
};

struct Data{
	void set(int arg_row,int arg_col){
		row = arg_row;
		col = arg_col;
	}
	int row,col;
};

struct Info{
	Info(int arg_row,int arg_col,int arg_sum_cost,int arg_node_loc){
		row = arg_row;
		col = arg_col;
		sum_cost = arg_sum_cost;
		node_loc = arg_node_loc;
	}
	bool operator<(const struct Info &arg) const{
		return sum_cost > arg.sum_cost;
	}
	int row,col,sum_cost,node_loc;
};


int H,W,POW[11];
int diff_row[4] = {-1,0,0,1},diff_col[4] = {0,-1,1,0};
int table[128],min_cost[50][50][200];
DIR dir_table[4] = {North,East,South,West};

char base_map[50][51];
Node nodes[200];
Data start,goal;
map<int,int> MAP;


bool rangeCheck(int row,int col){
	if(row >= 0 && row <= H-1 && col >= 0 && col <= W-1)return true;
	else{
		return false;
	}
}


void debug(DIR dir){

	switch(dir){
	case North:
		printf("U");
		break;
	case East:
		printf("R");
		break;
	case South:
		printf("D");
		break;
	case West:
		printf("L");
		break;
	}
}

void func(){

	for(int i = 0; i < 200; i++){
		nodes[i].finish_FLG = false;
		for(int k = 0; k < 4; k++)nodes[i].children[k] = -1;
	}

	for(int row = 0; row < H; row++){
		scanf("%s",base_map[row]);
		for(int col = 0; col < W; col++){
			if(base_map[row][col] == 'S'){

				start.set(row,col);

			}else if(base_map[row][col] == 'G'){

				goal.set(row,col);

			}
		}
	}

	int P;
	scanf("%d",&P);

	nodes[0].parent_id = -1;
	nodes[0].num = 0;
	nodes[0].depth = 0;
	int node_index = 1,tmp_ch,tmp_loc,parent_id,tmp_index;
	char buf[11];
	MAP.clear();



	//トライ木を構成する
	for(int loop = 0; loop < P; loop++){

		//printf("\nloop:%d\n",loop);

		scanf("%s",buf);

		tmp_index = 0;
		tmp_ch = table[buf[tmp_index]];

		tmp_loc = 0;
		tmp_index = 0;

		while(true){

			parent_id = tmp_loc;

			if(nodes[tmp_loc].children[tmp_ch] == -1){

				nodes[tmp_loc].children[tmp_ch] = node_index++;
			}
			//小ノードに移動
			tmp_loc = nodes[tmp_loc].children[tmp_ch];

		/*	printf("tmp_loc:%d\n",tmp_loc);
			debug(dir_table[tmp_ch]);
			printf("\n");*/

			nodes[tmp_loc].parent_id = parent_id;
			//文字列をコピー&追加
			for(int i = 0; i < nodes[parent_id].depth; i++){
				nodes[tmp_loc].pattern[i] = nodes[parent_id].pattern[i];
			}
			nodes[tmp_loc].pattern[nodes[parent_id].depth] = dir_table[tmp_ch];
			nodes[tmp_loc].depth = nodes[parent_id].depth+1;

			tmp_index++;

			//配列をコード化
			nodes[tmp_loc].num = -1;
			for(int  i = 0; i < nodes[tmp_loc].depth; i++){
				nodes[tmp_loc].num += (nodes[tmp_loc].pattern[i]+1)*POW[i]; //★ハマりpoint★
			}
			//printf("num:%d\n",nodes[tmp_loc].num);
			MAP[nodes[tmp_loc].num] = tmp_loc;

			if(buf[tmp_index] == '\0'){
				nodes[tmp_loc].finish_FLG = true;
				//printf("%dにてfinish\n",tmp_loc);

				break;
			}
			tmp_ch = table[buf[tmp_index]];
		}
	}

	int tmp,start_pos;
	bool Found;

	//printf("\n");

	//サフィックスリンクを張る
	for(int i = 1; i < node_index; i++){

		/*printf("nodes[%d] ",i);
		for(int k = 0; k < nodes[i].depth; k++){
			debug(nodes[i].pattern[k]);
		}
		printf("\n");*/

		Found = false;
		start_pos = 1;
		//遷移できる場所を探す
		while(start_pos < nodes[i].depth){

			//printf("start_pos:%d\n",start_pos);

			tmp = -1;
			for(int k = start_pos; k < nodes[i].depth; k++){
				tmp += (nodes[i].pattern[k]+1)*POW[k-start_pos];
			}

			//printf("tmp:%d\n",tmp);

			auto at = MAP.find(tmp);
			if(at != MAP.end()){
				Found = true;
				break;
			}
			start_pos++;
		}

		if(!Found){ //接続できるノードがないので、ルートノードに貼る
			//printf("原点にsuffix_linkを張った\n");
			nodes[i].suffix_link = 0;
		}else{
			//printf("%dにsuffix_linkを張った\n",MAP[tmp]);
			nodes[i].suffix_link = MAP[tmp];
		}
	}

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			for(int node_loc = 0; node_loc < node_index; node_loc++)min_cost[row][col][node_loc] = BIG_NUM;
		}
	}

	min_cost[start.row][start.col][0] = 0;

	priority_queue<Info> Q;
	Q.push(Info(start.row,start.col,0,0));

	int next_node_pos,adj_row,adj_col;
	DIR next_dir;

	bool FLG;

	int calc;

	while(!Q.empty()){

		if(Q.top().row == goal.row && Q.top().col == goal.col){

			printf("%d\n",Q.top().sum_cost); //Qをコストの小さい順に回しているから、最速でゴールするデータは最速で遷移してくるはず
			return;

		}else if(Q.top().sum_cost > min_cost[Q.top().row][Q.top().col][Q.top().node_loc]){
			Q.pop();
		}else{

			for(int i = 0; i < 4; i++){
				adj_row = Q.top().row+diff_row[i];
				adj_col = Q.top().col+diff_col[i];

				if(rangeCheck(adj_row,adj_col) == false || base_map[adj_row][adj_col] == '#')continue;

				switch(i){
				case 0:
					next_dir = North;
					break;
				case 1:
					next_dir = West;
					break;
				case 2:
					next_dir = East;
					break;
				case 3:
					next_dir = South;
					break;
				}

				//printf("現在:(%d,%d) next:(%d,%d)\n",Q.top().row,Q.top().col,adj_row,adj_col);
				/*debug(next_dir);
				printf("\n");*/

				if(nodes[Q.top().node_loc].children[next_dir] != -1){ //子に遷移できる

					//printf("子に遷移できる\n");

					next_node_pos = nodes[Q.top().node_loc].children[next_dir];

				}else{ //行き止まり

					//printf("行き止まり\n");

					if(Q.top().node_loc == 0){ //原点の場合<suffix_linkが未定義>

						next_node_pos = 0;

						if(min_cost[adj_row][adj_col][next_node_pos] > Q.top().sum_cost+1){
							min_cost[adj_row][adj_col][next_node_pos] = Q.top().sum_cost+1;
							Q.push(Info(adj_row,adj_col,Q.top().sum_cost+1,next_node_pos));
						}

						continue;
					}

					tmp = nodes[Q.top().node_loc].suffix_link;

					while(tmp != 0 && nodes[tmp].children[next_dir] == -1){
						tmp = nodes[tmp].suffix_link;
					}

					//遷移先、およびそのsiffix_link列の中にfinish_FLGがtrueになっているものがないか調べる
					tmp = next_node_pos;

					//printf("next_node_pos:%d\n",next_node_pos);

					while(tmp != 0){
						if(nodes[tmp].finish_FLG){
							//printf("nodes[%d]でfinish_FLG\n",tmp);
							FLG = false;
							break;
						}
						tmp = nodes[tmp].suffix_link;
					}

					if(!FLG)continue; //禁止パターンに抵触

					if(min_cost[adj_row][adj_col][next_node_pos] > Q.top().sum_cost+1){
						min_cost[adj_row][adj_col][next_node_pos] = Q.top().sum_cost+1;
						Q.push(Info(adj_row,adj_col,Q.top().sum_cost+1,next_node_pos));
					}
			}
			Q.pop();
		}
	}
	printf("-1\n");
}


int main(){

	for(int i = 0; i < 11; i++)POW[i] = pow(4,i);

	table['U'] = North;
	table['R'] = East;
	table['D'] = South;
	table['L'] = West;

	while(true){
		scanf("%d %d",&H,&W);
		if(H == 0 && W == 0)break;

		func();
	}
	return 0;
}



Compiler output:
a.cc: In function 'void func()':
a.cc:338:9: warning: empty parentheses were disambiguated as a function declaration [-Wvexing-parse]
  338 | int main(){
      |         ^~
a.cc:338:9: note: remove parentheses to default-initialize a variable
  338 | int main(){
      |         ^~
      |         --
a.cc:338:9: note: or replace parentheses with braces to value-initialize a variable
a.cc:338:11: error: a function-definition is not allowed here before '{' token
  338 | int main(){
      |           ^
a.cc:354:2: error: expected '}' at end of input
  354 | }
      |  ^
a.cc:93:12: note: to match this '{'
   93 | void func(){
      |            ^