Problem:
Problem D:バトルタウン

あなたは友人たちとゲームを開発することにした．
ゲームのタイトルは「バトルタウン」．
戦車による市街戦をテーマにしたゲームだ．
ゲーム開発の第一歩として，次のようなプロトタイプを開発することにした．

このプロトタイプでは，登場する戦車はプレイヤーの戦車のみであり，
敵の戦車は登場しない．
プレイヤーの戦車はプレイヤーの入力に従ってマップ上で様々な動作をする．
以下に，戦車の動作に関する仕様を述べる．

マップの構成要素は表1の通りである．
戦車が移動できるのはマップ内の平地の上だけである．

表1: マップの構成要素

文字

要素

.

平地

*

レンガの壁

#

鉄の壁

-

水

^

戦車（上向き）

v

戦車（下向き）

<

戦車（左向き）

>

戦車（右向き）

プレイヤーの入力は文字の列で与えられる．
各文字に対応する動作は表2の通りである．

表2: プレイヤーの入力に対する動作

文字

動作

U

Up: 戦車を上向きに方向転換し，さらに一つ上のマスが平地ならばそのマスに移動する

D

Down: 戦車を下向きに方向転換し，さらに一つ下のマスが平地ならばそのマスに移動する

L

Left: 戦車を左向きに方向転換し，さらに一つ左のマスが平地ならばそのマスに移動する

R

Right: 戦車を右向きに方向転換し，さらに一つ右のマスが平地ならばそのマスに移動する

S

Shoot: 戦車が現在向いている方向に砲弾を発射する

砲弾はレンガの壁あるいは鉄の壁にぶつかるか，マップの外に出るまで直進する．
レンガの壁にぶつかった場合は，砲弾は消滅し，レンガの壁は平地に変化する．
鉄の壁にぶつかった場合は，砲弾は消滅するが，鉄の壁は変化しない．
マップの外に出たときは砲弾はそのまま消滅する．

あなたの仕事は，初期マップとプレイヤーの入力操作列が与えられたときに，
最終的なマップの状態を出力するプログラムを作成することである．

Input

入力の1行目にはデータセット数を表す数 T
(0 < T ≤ 100) が与えられる．
この行に引き続き T 個のデータセットが与えられる．

各データセットの1行目にはマップの高さと幅を表す整数
H と W が
1つの空白文字で区切られて与えられる．
これらの整数は 2 ≤ H ≤ 20,
2 ≤ W ≤ 20 を満たす．
続く H 行はマップの初期状態を表す．
各行は長さ W の文字列である．
マップに含まれる文字はすべて表1で定義されたものであり，
全体でちょうど1つの戦車を含む．
マップに続く行には入力操作列の長さ N
(0 < N ≤ 100) が与えられ，
次の行には入力操作列を表す長さ N の文字列が与えられる．
入力操作列は表2で定義された文字のみからなる文字列である．

Output

各データセットに対し，すべての入力操作を終えた後のマップを，
入力マップと同じ形式で出力せよ．
データセットの間には1行の空行を出力せよ．
最後のデータセットの後に余計な空行を出力しないよう注意すること．

Sample Input

4
4 6
*.*..*
*.....
..-...
^.*#..
10
SRSSRRUSSR
2 2
<.
..
12
DDSRRSUUSLLS
3 5
>-#**
.-*#*
.-**#
15
SSSDRSSSDRSSSUU
5 5
v****
*****
*****
*****
*****
44
SSSSDDRSDRSRDSULUURSSSSRRRRDSSSSDDLSDLSDLSSD

Output for the Sample Input

*....*
......
..-...
..>#..

<.
..

^-#**
.-.#*
.-..#

.....
.***.
..*..
..*..
....v

Solution in JAVA (judge verdict: Wrong Answer)

import java.util.Scanner;

public class Main {

	// マップ

	// 戦車
	class Tank {

		char[][] map;

		int x, y; 	  // 座標
		char dir; 	  // 向いてる方角

		int bx=-1, by=-1;   // 砲弾の座標

		public Tank(int x, int y,  int dir, char[][] map) {
			this.x = x;
			this.y = y;
			this.map = map;
			if(dir == 0) this.dir = 'L';
			else if(dir == 1) this.dir = 'U';
			else if(dir == 2) this.dir = 'R';
			else if(dir == 3) this.dir = 'D';
		}

		// 命令
		// rの取りうる値: UDLR
		public void order(char r) {

			// 回転し、進めるのであれば進む
			if(r == 'U') {
				dir = 'U';
				map[y][x] = '^';
				if(isMovable(x, y-1)) {
					map[y][x] = '.';
					y -= 1;
					// マップ情報を更新する
					map[y][x] = '^';
				} else {
					// 方向転換だけ行う
					map[y][x] = '<';
				}
			} else if(r == 'D') {
				dir = 'D';
				map[y][x] = 'v';
				if(isMovable(x, y+1)) {
					map[y][x] = '.';
					y += 1;
					//					// マップ情報を更新する
					map[y][x] = 'v';
				}
			} else if(r == 'L') {
				dir = 'L';
				map[y][x] = '<';
				if(isMovable(x-1, y)) {
					map[y][x] = '.';
					x -= 1;
					map[y][x] = '<';
				}
			} else if(r == 'R') {
				dir = 'R';
				map[y][x] = '>';
				if(isMovable(x+1, y)) {
					map[y][x] = '.';
					x += 1;
					map[y][x] = '>';
				}
			} else if(r == 'S') {
				shot(dir);
			}

		}

		// 砲撃
		public void shot(char dir) {

			// 砲弾の位置初期化
			bx = x;
			by = y;

			// 方向を設定し発射
			moveBullet(dir);

		}

		// 砲弾の移動
		public void moveBullet(char dir) {

			// 移動先座標
			int toX = -1;
			int toY = -1;
			if(dir == 'L') {
				toX = bx-1;
				toY = by;
				bx -= 1;
			} else if(dir == 'U') {
				toX = bx;
				toY = by-1;
				by -= 1;
			} else if(dir == 'R') {
				toX = bx+1;
				toY = by;
				bx += 1;
			} else if(dir == 'D') {
				toX = bx;
				toY = by+1;
				by += 1;
			}

			// 指定座標に移動できれば破壊し移動する
			if(map[toY][toX] == '*') {
				// 破壊
				map[toY][toX] = '.';
				return;
			} else if(map[toY][toX] == '#') {
				return;
			} else {
				moveBullet(dir);
			}
		}

		// 指定の座標に戦車が進めるか
		public boolean isMovable(int x, int y) {

			if(map[y][x] == '.') return true;
			else return false;

		}

		// マップを表示
		public void drawMap() {
			for(int i=1; i<map.length-1; i++) {
				for(int j=1; j<map[i].length-1; j++){
					System.out.print(map[i][j]);
				}
				System.out.println("");
			}
		}

	}

	// マップから戦車の位置と向きを取得する
	// @return int[] [0]戦車のx座標, [1]戦車のy座標, [2]戦車の向き(左から時計回りに0~3)
	public int[] getTankDir(char[][] map) {

		int[] ret = new int[3];
		for(int i=0; i<map.length; i++) {
			for(int j=0; j<map[i].length; j++){
				if(map[i][j] == '<') {
					ret[0] = j;
					ret[1] = i;
					ret[2] = 0;
				} else if(map[i][j] == '^') {
					ret[0] = j;
					ret[1] = i;
					ret[2] = 1;
				} else if(map[i][j] == '>') {
					ret[0] = j;
					ret[1] = i;
					ret[2] = 2;
				} else if(map[i][j] == 'v') {
					ret[0] = j;
					ret[1] = i;
					ret[2] = 3;
				}
			}
		}

		return ret;

	}

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);

		// マップセットの個数入力
		int num = sc.nextInt();

		for(int n=0; n<num; n++) {

			// 地図データの入力
			int y = sc.nextInt();
			int x = sc.nextInt();

			char[][] map = new char[y+2][x+2];

			// 外を埋める
			for(int i=0; i<y+2; i++) {
				for(int j=0; j<x+2; j++) {
					if(i == 0 || i == y+1 || j == 0 || j == x+1) map[i][j] = '#';
				}
			}

			for(int i=1; i<y+1; i++) {
				String line = sc.next();
				for(int j=1; j<x+1; j++) {
					map[i][j] = line.toCharArray()[j-1];
				}
			}

			// 命令を入力
			int orderNum = sc.nextInt();
			String orders = sc.next();
			char[] orderArr = orders.toCharArray();

			Main b = new Main();

			// 戦車の初期位置と向きを取得
			int[] tankPos = b.getTankDir(map);


			// 戦車を生成
			Tank t = new Main().new Tank(tankPos[0], tankPos[1], tankPos[2], map);

			// 命令を実行
			for(int i=0; i<orderNum; i++) {
				t.order(orderArr[i]);
			}


			// debug
			// 戦車の移動テスト
			//		t.rotate('L');

			// マップを再表示
			t.drawMap();
			if(n != num-1) System.out.println("");

		}

		sc.close();


	}

}