[SWEA] 1873. 상호의 배틀필드
다음 표는 게임 맵의 구성 요소를 나타낸다.
문자 | 의미 |
. | 평지(전차가 들어갈 수 있다.) |
* | 벽돌로 만들어진 벽 |
# | 강철로 만들어진 벽 |
- | 물(전차는 들어갈 수 없다.) |
^ | 위쪽을 바라보는 전차(아래는 평지이다.) |
v | 아래쪽을 바라보는 전차(아래는 평지이다.) |
< | 왼쪽을 바라보는 전차(아래는 평지이다.) |
> | 오른쪽을 바라보는 전차(아래는 평지이다.) |
다음 표는 사용자가 넣을 수 있는 입력의 종류를 나타낸다.
문자 | 동작 |
U | Up : 전차가 바라보는 방향을 위쪽으로 바꾸고, 한 칸 위의 칸이 평지라면 위 그 칸으로 이동한다. |
D | Down : 전차가 바라보는 방향을 아래쪽으로 바꾸고, 한 칸 아래의 칸이 평지라면 그 칸으로 이동한다. |
L | Left : 전차가 바라보는 방향을 왼쪽으로 바꾸고, 한 칸 왼쪽의 칸이 평지라면 그 칸으로 이동한다. |
R | Right : 전차가 바라보는 방향을 오른쪽으로 바꾸고, 한 칸 오른쪽의 칸이 평지라면 그 칸으로 이동한다. |
S | Shoot : 전차가 현재 바라보고 있는 방향으로 포탄을 발사한다. |
[입력]
첫 번째 줄에 테스트 케이스의 수 T가 주어진다.
각 테스트 케이스의 첫 번째 줄에는 두 정수 H, W (2 ≤ H, W ≤ 20) 이 공백으로 구분되어 주어진다.
이는 게임 맵의 높이가 H, 너비가 W임을 나타낸다.
즉, 게임 맵은 H x W크기의 격자판이다.
다음 H개의 각각의 줄에는 길이가 W인 문자열이 주어진다.
각각의 문자는 위의 게임 맵 구성 요소 표에 있는 문자들만 포함하며, 전차는 단 하나만 있다.
다음 줄에는 사용자가 넣을 입력의 개수를 나타내는 정수 N(0 < N ≤ 100) 이 주어진다.
다음 줄에는 길이가 N인 문자열이 주어진다.
각각의 문자는 위의 사용자가 넣을 수 있는 입력의 종류를 나타내는 표에 있는 문자들만 포함된다.
[출력]
각 테스트 케이스마다 ‘#x’(x는 테스트케이스 번호를 의미하며 1부터 시작한다)를 출력하고 한 칸을 띄운 후, 모든 입력을 처리하고 난 후의 게임 맵을 H개의 줄에 걸쳐 출력한다.
[풀이]
U,D,L,R 을 만나면 무조건 그자리에서 방향을 틀어주고 평지일 경우에만 그 방향으로 한칸 이동해준다.
이러한 상화좌우탐색을 위해 d 라는 2차원 배열을 설정해주고 이를 더한 변수를 인덱스로 지정해 이동해주었다.
S 은 공격행위인데 현재 전차가 있는 방향으로 포탄을 발사한다.
따라서 현재 전차 위치의 인덱스를 저장한 곳에서 전차가 어떤 방향인지 확인하고 그에 해당하는 d 인덱스를 가져온다.
포탄은 맵 배열 안에서 유효하며 벽 하나가 맞을 때까지 간다.
평지와 물을 만나면 계속 포탄은 이동하고 강철벽을 만나면 사라진다.
이를 위해 do while문으로 구성을 해주었다.
코드가 길어 복잡하게 느껴질 수 있지만 처음부터 차례대로 구현하는 시뮬레이션 문제이다.
public class al1873 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int T;
T=sc.nextInt();
int[][] d = {{-1,0},{1,0},{0,-1},{0,1}};
HashMap<Character, Integer> map = new HashMap<>();
map.put('^', 0);
map.put('v', 1);
map.put('<', 2);
map.put('>', 3);
for(int test_case = 1; test_case <= T; test_case++)
{
int r = sc.nextInt();
int c = sc.nextInt();
int ni = 0, nj = 0;
char[][] arr = new char[r][c];
for (int i = 0; i < r; i++) {
arr[i] = sc.next().toCharArray();
for (int j = 0; j < c; j++) {
if(arr[i][j] == '<' || arr[i][j] == '>' || arr[i][j] == '^' || arr[i][j] == 'v') {
ni = i;
nj = j;
}
}
}
int n = sc.nextInt();
String str = sc.next();
int k = 0;
int si = ni, sj = nj;
int nr = 0, nc = 0;
for (int i = 0; i < n; i++) {
char ch = str.charAt(i);
char go = '.';
if(ch == 'U' || ch == 'D'|| ch == 'L' || ch == 'R') {
if(ch == 'U') {
go = '^';
k = 0;
}else if(ch == 'D') {
go = 'v';
k = 1;
}else if(ch == 'L') {
go = '<';
k = 2;
}else if(ch == 'R') {
go = '>';
k = 3;
}
arr[ni][nj] = go;
nr = ni + d[k][0];
nc = nj + d[k][1];
if(nr >= 0 && nr < r && nc >= 0 && nc < c && arr[nr][nc] == '.') {
arr[ni][nj] = '.';
arr[nr][nc] = go;
ni = nr;
nj = nc;
}
si = ni;
sj = nj;
}else if(str.charAt(i) == 'S') {
if(si >= 0 && si < r && sj >= 0 && sj < c && map.get(arr[si][sj]) != null){
k = map.get(arr[si][sj]);
}
int count = 0;
do {
nr = si + d[k][0];
nc = sj + d[k][1];
if(nr >= 0 && nr < r && nc >= 0 && nc < c) {
if(arr[nr][nc] == '*') {
arr[nr][nc] = '.';
count = 1;
}else if(arr[nr][nc] == '#') {
break;
}
si = nr;
sj = nc;
}else {
break;
}
}while(count == 0);
}
}
System.out.print("#" + test_case + " ");
for (char[] ks : arr) {
for (char ks2 : ks) {
System.out.print(ks2);
}
System.out.println();
}
}
}
}
- 38,152 kb메모리
- 226 ms실행시간
- 3,861코드길이
- Pass결과
'programming > 알고리즘 풀이' 카테고리의 다른 글
[백준(Baekjoon)] 2493. 탑 (0) | 2021.08.10 |
---|---|
[SWEA] 3499. 퍼펙트 셔플 (0) | 2021.08.06 |
[SWEA] 1218. 괄호 짝짓기 (0) | 2021.08.05 |
[SWEA] 2001. 파리 퇴치 (0) | 2021.08.05 |
[SWEA] 2805. 농작물 수확하기 (0) | 2021.08.04 |
댓글