728x90
shoot을 할 때 각 방향을 정의하기 위해 HashMap을 활용하였다.
각 방향을 key로 하고, 방향에 따라 달라지는 dr과 dc를 길이 2의 배열에 담아 value로 지정하였다.
HashMap<Character, Integer[]> dir = new HashMap<>();
// 각 방향의 dr dc
dir.put('<', new Integer[] { 0, -1 });
dir.put('>', new Integer[] { 0, 1 });
dir.put('^', new Integer[] { -1, 0 });
dir.put('v', new Integer[] { 1, 0 });
그리고 입력받은 문자열을 char 하나씩 문자열 배열로 만들었다.
StringTokenizer st = new StringTokenizer(br.readLine());
int H = Integer.parseInt(st.nextToken()); // row
int W = Integer.parseInt(st.nextToken()); // col
char[][] map = new char[H][W];
for (int h = 0; h < H; h++) {
String str = br.readLine();
for (int w = 0; w < W; w++) {
map[h][w] = str.charAt(w);
if (dir.containsKey(str.charAt(w))) {
r = h;
c = w;
}
}
}
각 입력에 따라 switch문으로 명령을 수행하였다.
먼저 shoot이 아닌 방향 변경은 해당 방향이 map의 범위 안에 있는지 확인하고, 범위 안에 있으면 그 땅이 평지인지 확인한다.
평지가 맞다면 자신이 있던 칸을 평지로 만들고 그 방향으로 이동한 후, r과 c좌표를 변경한다.
아니라면 자신의 방향만 바꿔준다.
U를 예시로 들면 다음 코드와 같다.
switch (com) {
case 'U':
if (r - 1 >= 0 && map[r - 1][c] == '.') { // 위칸이 평지라면
map[r][c] = '.'; // 자기가 있던 칸은 평지로 만들기
map[r - 1][c] = '^'; // 위 칸으로 이동
r--; // 좌표 변경
} else
map[r][c] = '^'; // 아니라면 이동x
break;
그리고 shoot은 먼저 현재 자신의 방향의 dr과 dc를 map을 통해 불러온다.
그렇게 새로운 nr과 nc를 구해서 map의 범위 내에 있으면 while문을 통해 반복한다.
1. 벽돌을 만나면 벽돌을 평지로 바꾸고 while문을 빠져 나온다.
2. 강철을 만나면 아무것도 하지 않고 while문을 빠져 나온다.
3. 두 경우가 아니라면 nr과 nc에 다시 dr, dc를 더해주고 같은 과정을 반복한다.
case 'S':
int dr = dir.get(map[r][c])[0]; // 해당 방향의 dr
int dc = dir.get(map[r][c])[1]; // 해당 방향의 dc
int nr = r + dr;
int nc = c + dc;
while (nr >= 0 && nr < H && nc >= 0 && nc < W) { // 맵 안에 있음
if (map[nr][nc] == '*') { // 벽돌로 만든 벽
map[nr][nc] = '.'; // 벽돌이 포탄 -> 평지가 됨
break;
} else if (map[nr][nc] == '#') // 강철로 만든 벽
break; // 그냥 소멸함
nr += dr;
nc += dc;
}
break;
}
전체 코드
package d3;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.StringTokenizer;
public class SWEA_1873_상호배틀 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
HashMap<Character, Integer[]> dir = new HashMap<>();
// 각 방향의 dr dc
dir.put('<', new Integer[] { 0, -1 });
dir.put('>', new Integer[] { 0, 1 });
dir.put('^', new Integer[] { -1, 0 });
dir.put('v', new Integer[] { 1, 0 });
StringBuilder sb = new StringBuilder();
for (int t = 1; t <= T; t++) {
int r = 0; // 전차 좌표
int c = 0;
StringTokenizer st = new StringTokenizer(br.readLine());
int H = Integer.parseInt(st.nextToken()); // row
int W = Integer.parseInt(st.nextToken()); // col
char[][] map = new char[H][W];
for (int h = 0; h < H; h++) {
String str = br.readLine();
for (int w = 0; w < W; w++) {
map[h][w] = str.charAt(w);
if (dir.containsKey(str.charAt(w))) {
r = h;
c = w;
}
}
}
int N = Integer.parseInt(br.readLine());
String command = br.readLine();
for (int i = 0; i < N; i++) {
char com = command.charAt(i);
switch (com) {
case 'U':
if (r - 1 >= 0 && map[r - 1][c] == '.') { // 위칸이 평지라면
map[r][c] = '.'; // 자기가 있던 칸은 평지로 만들기
map[r - 1][c] = '^'; // 위 칸으로 이동
r--; // 좌표 변경
} else
map[r][c] = '^'; // 아니라면 이동x
break;
case 'D':
if (r + 1 < H && map[r + 1][c] == '.') { // 아래칸이 평지라면
map[r][c] = '.'; // 자기가 있던 칸은 평지로 만들기
map[r + 1][c] = 'v'; // 아래칸으로 이동
r++; // 좌표 변경
} else
map[r][c] = 'v'; // 아니라면 이동x
break;
case 'L':
if (c - 1 >= 0 && map[r][c - 1] == '.') { // 왼쪽칸이 평지라면
map[r][c] = '.'; // 자기가 있던 칸은 평지로 만들기
map[r][c - 1] = '<'; // 왼쪽칸으로 이동
c--; // 좌표 변경
} else
map[r][c] = '<'; // 아니라면 이동x
break;
case 'R':
if (c + 1 < W && map[r][c + 1] == '.') { // 오른쪽칸이 평지라면
map[r][c] = '.'; // 자기가 있던 칸은 평지로 만들기
map[r][c + 1] = '>'; // 오른쪽칸으로 이동
c++; // 좌표 변경
} else
map[r][c] = '>'; // 아니라면 이동x
break;
case 'S':
int dr = dir.get(map[r][c])[0]; // 해당 방향의 dr
int dc = dir.get(map[r][c])[1]; // 해당 방향의 dc
int nr = r + dr;
int nc = c + dc;
while (nr >= 0 && nr < H && nc >= 0 && nc < W) { // 맵 안에 있음
if (map[nr][nc] == '*') { // 벽돌로 만든 벽
map[nr][nc] = '.'; // 벽돌이 포탄 -> 평지가 됨
break;
} else if (map[nr][nc] == '#') // 강철로 만든 벽
break; // 그냥 소멸함
nr += dr;
nc += dc;
}
break;
}
}
sb.append("#" + t + " ");
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
sb.append(map[i][j]);
}
sb.append("\n");
}
} // tc
System.out.print(sb.toString());
} // main
}
728x90
'문제 풀이 > SWEA' 카테고리의 다른 글
[SWEA] 2819 - 격자판의 숫자 이어 붙이기 (0) | 2022.08.25 |
---|---|
[SWEA] 1231 - 중위 순회 (0) | 2022.08.23 |
[SWEA] 1216 - 회문 2 (자바/Java) (0) | 2022.08.12 |
[SWEA] 1210 - Ladder (자바/Java) (0) | 2022.08.11 |
[SWEA] 5432 - 쇠막대기 자르기 (자바/Java) (0) | 2022.08.11 |