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: Accepted)


import java.io.IOException;
import java.util.HashMap;
import java.util.Scanner;

/**
 * <pre>
 * ??????????????????
 * </pre>
 *
 * @author ?????????????????§???
 * @version 1.8_45
 * @since 1.8_45
 */
public class Main {
	/*
	 * ????????°???????????¨?????????????????????
	 */
	public static void main(String[] args) throws NumberFormatException, IOException {
		// ?????????
		Scanner sc = new Scanner(System.in);
		// ?????????????????????????§?????????°
		int data_set = sc.nextInt();

		// ?????????????????§?????????????????????????????????????????¨
		int sysout_cnt = data_set;

		for (int game_cnt = 0; game_cnt < data_set; game_cnt++) {
			// ??????????????????,???????????????
			int map_height = sc.nextInt();
			int map_width = sc.nextInt();

			// ??????????????????????????±?????¶???????????????
			Tank tank = null;

			// ????????¨???????????£?????????????????????
			Map[][] game_Map = new Map[map_height][map_width];

			for (int mh = 0; mh < map_height; mh++) {
				// ????????????
				String tmp_row = sc.next();
				for (int mw = 0; mw < map_width; mw++) {
					// ??°??????????£?
					game_Map[mh][mw] = new Map(tmp_row.charAt(mw));

					if ("^v<>".indexOf(game_Map[mh][mw].getMap_info()) > -1) {
						// ????????????????????±????????????????´?
						tank = new Tank(game_Map[mh][mw].getMap_info(), new int[] { mh, mw });
						game_Map[mh][mw] = new Map('.');
					}
				}
			}
			// ???????????°
			int cmd_set = sc.nextInt();
			// ?????????????????????
			String tmp_cmdRow = sc.next();

			// ????????????????????¨???????????????
			Map mp = new Map(map_height, map_width);
			for (int cnt = 0; cnt < cmd_set; cnt++) {
				tank_Action(mp, tank, game_Map, tmp_cmdRow.charAt(cnt));
			}

			// ????????????????????????????????±?????¨?¨???????
			last_tankLocate(tank, game_Map);

			// ????????????
			sysout_cnt--;

			// ??????????????????
			for (int ch = 0; ch < map_height; ch++) {
				for (int cw = 0; cw < map_width; cw++) {
					System.out.print(game_Map[ch][cw].getMap_info());
				}
				System.out.println();
			}
			// AOJ?????????????§???????????????????????????????????????????
			if (sysout_cnt > 0) {
				System.out.println();
			}
		} // for?????????????????????

		// ????????°??????????????????
		sc.close();
	}// ?????????????????????????????????

	/**
	 * ?????????????????¨??°?????°????????¨?¨???????
	 */
	private static void last_tankLocate(Tank tank, Map[][] game_Map) {

		game_Map[tank.getPos()[0]][tank.getPos()[1]] = new Map(tank.getDir());

	}// last_tankLocate????????????????????????

	/**
	 * ??????????????£????§????????????????????????????
	 *
	 * @param mp
	 *            ??????????????????????????¶
	 * @param game_Map
	 *            ??????????????°??????????????????
	 * @param tank
	 *            ??????????????????????????¶
	 * @param cmd
	 *            ??????
	 */
	private static void tank_Action(Map mp, Tank tank, Map[][] game_Map, char cmd) {
		/*
		 * ?§????
		 */
		if (cmd != 'S') {
			// ????????????????????¨?????????????????????
			tank.setDir(tank.getCmd_Map().get(cmd));
			int[] move = new int[] { tank.getPos()[0], tank.getPos()[1] };
			switch (tank.getDir()) {
			// ('U', '^');
			// ('^', { -1, 0 });
			case '^':
				if (move[0] - 1 >= 0) {
					move[0] += mp.getDir_Map().get(tank.getDir())[0];
					if (game_Map[move[0]][move[1]].getMap_info() == '.') {
						tank.setPos(move);
					}
				}
				break;

			// ('D', 'v');
			// ('v', { 1, 0 });
			case 'v':
				if (move[0] + 1 < mp.getHeight()) {
					move[0] += mp.getDir_Map().get(tank.getDir())[0];
					if (game_Map[move[0]][move[1]].getMap_info() == '.') {
						tank.setPos(move);
					}
				}
				break;
			// ('L', '<');
			// ('<', { 0, -1 });
			case '<':
				if (move[1] - 1 >= 0) {
					move[1] += mp.getDir_Map().get(tank.getDir())[1];
					if (game_Map[move[0]][move[1]].getMap_info() == '.') {
						tank.setPos(move);
					}
				}
				break;
			// ('R', '>');
			// ('>',{ 0, 1 });
			case '>':
				if (move[1] + 1 < mp.getWidth()) {
					move[1] += mp.getDir_Map().get(tank.getDir())[1];
					if (game_Map[move[0]][move[1]].getMap_info() == '.') {
						tank.setPos(move);
					}
				}
				break;
			}
			/*
			 * ??????
			 *
			 * ????????? ?????????????????¨??????????????£???if-else if???????????¨??? ??????????????£???????¬??????????????????§????????????????????????????¨????
			 */
		} else {
			// ???????????????????¨????
			int[] shell = new int[] { tank.getPos()[0], tank.getPos()[1] };
			// ??????????????????????????????
			switch (tank.getDir()) {
			// ('^', { -1, 0 });
			case '^':
				for (int cnt = shell[0]; cnt >= 0; cnt--) {
					if (game_Map[cnt][shell[1]].getMap_info() == '*') {
						game_Map[cnt][shell[1]] = new Map('.');
						break;
					} else if (game_Map[cnt][shell[1]].getMap_info() == '#') {
						break;
					}
				}
				break;
			// ('v',{ 1, 0 });
			case 'v':
				for (int cnt = 1; cnt < (mp.getHeight()) - shell[0]; cnt++) {
					if (game_Map[shell[0] + cnt][shell[1]].getMap_info() == '*') {
						game_Map[shell[0] + cnt][shell[1]] = new Map('.');
						break;
					} else if (game_Map[shell[0] + cnt][shell[1]].getMap_info() == '#') {
						break;
					}
				}
				break;
			// ('<', { 0, -1 });
			case '<':
				for (int cnt = shell[1]; cnt >= 0; cnt--) {
					if (game_Map[shell[0]][cnt].getMap_info() == '*') {
						game_Map[shell[0]][cnt] = new Map('.');
						break;
					} else if (game_Map[shell[0]][cnt].getMap_info() == '#') {
						break;
					}
				}
				break;
			// ('>', { 0, 1 });
			case '>':
				for (int cnt = 1; cnt < (mp.getWidth()) - shell[1]; cnt++) {
					if (game_Map[shell[0]][shell[1] + cnt].getMap_info() == '*') {
						game_Map[shell[0]][shell[1] + cnt] = new Map('.');
						break;
					} else if (game_Map[shell[0]][shell[1] + cnt].getMap_info() == '#') {
						break;
					}
				}
				break;
			}
		}
	} // tank_Action????????????????????????
}// ??????????????????????????????

class Tank {
	/**
	 * ??????????????¨??°
	 */
	private int[] pos;

	/**
	 * ??????
	 */
	private char dir;

	public int[] getPos() {
		return pos;
	}

	public void setPos(int[] position) {
		this.pos = position;
	}

	public char getDir() {
		return dir;
	}

	public void setDir(char direction) {
		this.dir = direction;
	}

	public Tank(char direction, int[] tank_pos) {
		this.dir = direction;
		this.pos = tank_pos;
	}

	/**
	 * ?§??????????????????????
	 */
	private HashMap<Character, Character> cmd_Map = new HashMap<Character, Character>() {
		{
			put('U', '^');
			put('D', 'v');
			put('L', '<');
			put('R', '>');
		}
	};

	// ?????????????°???¨
	public HashMap<Character, Character> getCmd_Map() {
		return cmd_Map;
	}

}// Tank?????????????????????

class Map {

	/**
	 * ??°??¢?????±
	 */
	private char map_info;

	/**
	 * ??????????????????
	 */
	private int height;

	/**
	 * ??????????????????
	 */
	private int width;

	public char getMap_info() {
		return map_info;
	}

	public void setMap_info(char map_info) {
		this.map_info = map_info;
	}

	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	public int getWidth() {
		return width;
	}

	public void setWidth(int width) {
		this.width = width;
	}

	public Map() {

	}

	public Map(char info) {
		map_info = info;
	}

	public Map(int map_height, int map_width) {
		this.height = map_height;
		this.width = map_width;
	}

	/**
	 * ?§??????¢???????????????
	 */
	private HashMap<Character, int[]> dir_Map = new HashMap<Character, int[]>() {
		{
			put('^', new int[] { -1, 0 });
			put('v', new int[] { 1, 0 });
			put('<', new int[] { 0, -1 });
			put('>', new int[] { 0, 1 });
		}
	};

	// ?????????????°???¨
	public HashMap<Character, int[]> getDir_Map() {
		return dir_Map;
	}

}// Map?????????????????????