SW Expert Academy
SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!
swexpertacademy.com
💡풀이💡
문제에서 제시한 기준에 따라 동작하게 하기!! >> 시뮬레이션
문제를 처음 읽을 때 방향이나 맵 구성 요소가 많아 계속 문제를 참고하면서 했기 때문에 중간 중간에 내가 헷갈리지 않게 하려고 코드를 최대한 깔끔하게 짜려고 했다.
기능 별로 메서드 전부 분리 :: play(), move(), shoot()
탱크 정보 저장 :: Tank 클래스 생성
1. 입력 받기
탱크는 무조건 1개만 등장하기 때문에 맵 정보를 받을 때 들어오는 전차의 위치와 방향을 tank 객체에 저장
명령어는 1차원 char 배열로 만들 수 있기 때문에 for문 사용하는 대신 toCharArray 메서드로 바로 만들어줌
class Tank {
int r;
int c;
char dir;
public Tank(int r, int c, char dir) {
this.r = r;
this.c = c;
this.dir = dir;
}
}
static int R, C, N;
static char[][] map;
static char[] inputs;
static Tank tank;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int T = Integer.parseInt(br.readLine());
for(int t=1; t<=T; t++) {
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
R = Integer.parseInt(st.nextToken());
C = Integer.parseInt(st.nextToken());
map = new char[R][C];
for(int i=0; i<R; i++) {
String str = br.readLine();
for(int j=0; j<C; j++) {
map[i][j] = str.charAt(j);
if(map[i][j]=='^') tank = new Tank(i,j,'u');
else if(map[i][j]=='v') tank = new Tank(i,j,'d');
else if(map[i][j]=='<') tank = new Tank(i,j,'l');
else if(map[i][j]=='>') tank = new Tank(i,j,'r');
}
}
N = Integer.parseInt(br.readLine());
String str = br.readLine();
inputs = str.toCharArray();
br.close();
}
2. 명령어 실행
명령어는 크게 이동 관련 명령어와 포탄 발사하는
명령어로 나뉘기 때문에 둘로 나누어 메서드를 생성
2-1. 포탄 쏘기
위쪽/아래쪽으로 발사이면 현재 탱크의 r 위치를,
왼쪽/오른쪽으로 발사이면 현재 탱크의 c 위치를 가져옴
맵 범위를 벗어나거나 벽을 만나면 break
그 외에는 계속 직진
📌놓쳤던 부분
맵 범위를 벗어나는 조건과 벽을 만나는 조건을 한번에 if문에 썼기 때문에 벽일 때 벽이 부숴지는 부분 코드에서 범위 체크를 한 번 더 해줬어야 하는데 안 했어서 계속 ArrayIndexOutOfBounds 에러가 났다…
// 벽에 부딪히거나 맵 밖으로 나갈 때까지 직진
static void shoot() {
// 위쪽으로 발사
if(tank.dir == 'u') {
int bomb=tank.r;
while(true) {
if(bomb<0 || map[bomb][tank.c]=='*' || map[bomb][tank.c]=='#') {
if(0<=bomb && map[bomb][tank.c]=='*') map[bomb][tank.c]='.';
break;
}
bomb--;
}
}
// 아래쪽으로 발사
else if(tank.dir == 'd') {
int bomb=tank.r;
while(true) {
if(bomb>=R || map[bomb][tank.c]=='*' || map[bomb][tank.c]=='#') {
if(bomb<R && map[bomb][tank.c]=='*') map[bomb][tank.c]='.';
break;
}
bomb++;
}
}
// 왼쪽으로 발사
else if(tank.dir == 'l') {
int bomb=tank.c;
while(true) {
if(bomb<0 || map[tank.r][bomb]=='*' || map[tank.r][bomb]=='#') {
if(0<=bomb && map[tank.r][bomb]=='*') map[tank.r][bomb]='.';
break;
}
bomb--;
}
}
// 오른쪽으로 발사
else {
int bomb=tank.c;
while(true) {
if(bomb>=C || map[tank.r][bomb]=='*' || map[tank.r][bomb]=='#') {
if(bomb<C && map[tank.r][bomb]=='*') map[tank.r][bomb]='.';
break;
}
bomb++;
}
}
}
2-2. 이동
명령에 따라 탱크가 지도 범위 안에 있고 이동하려는 방향이 평지이면 탱크 이동하기
탱크의 좌표만 바꾸기 때문에 모든 명령이 끝나고 탱크의 위치에 탱크 방향에 맞게 넣어주기
📌놓쳤던 부분
탱크가 이동을 하던 하지 못하던 이동 명령이 들어오면 그 방향으로 탱크의 방향은 무조건 바꿔줘야 한다. 탱크가 이동을 할 때만 방향을 바꾸게 해서 잘못된 결과가 나왔다
// 전차 이동
static void move(char order) {
map[tank.r][tank.c] = '.';
if(order == 'U') {
tank.dir = 'u';
if(0<=tank.r-1 && map[tank.r-1][tank.c]=='.') tank.r-=1;
}
else if(order == 'D') {
tank.dir = 'd';
if(tank.r+1<R && map[tank.r+1][tank.c]=='.') tank.r+=1;
}
else if(order == 'L') {
tank.dir = 'l';
if(0<=tank.c-1 && map[tank.r][tank.c-1]=='.') tank.c-=1;
}
else {
tank.dir = 'r';
if(tank.c+1<C && map[tank.r][tank.c+1]=='.') tank.c +=1;
}
}
// 명령 끝난 후 탱크 위치 저장
if(tank.dir=='u') map[tank.r][tank.c] = '^';
else if(tank.dir=='d') map[tank.r][tank.c] = 'v';
else if(tank.dir=='l') map[tank.r][tank.c] = '<';
else if(tank.dir=='r') map[tank.r][tank.c] = '>';
전체 코드
package ps_02222;
import java.io.*;
import java.util.*;
class Tank {
int r;
int c;
char dir;
public Tank(int r, int c, char dir) {
this.r = r;
this.c = c;
this.dir = dir;
}
}
public class SW1873 {
static int R, C, N;
static char[][] map;
static char[] inputs;
static Tank tank;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int T = Integer.parseInt(br.readLine());
for(int t=1; t<=T; t++) {
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
R = Integer.parseInt(st.nextToken());
C = Integer.parseInt(st.nextToken());
map = new char[R][C];
for(int i=0; i<R; i++) {
String str = br.readLine();
for(int j=0; j<C; j++) {
map[i][j] = str.charAt(j);
if(map[i][j]=='^') tank = new Tank(i,j,'u');
else if(map[i][j]=='v') tank = new Tank(i,j,'d');
else if(map[i][j]=='<') tank = new Tank(i,j,'l');
else if(map[i][j]=='>') tank = new Tank(i,j,'r');
}
}
N = Integer.parseInt(br.readLine());
String str = br.readLine();
inputs = str.toCharArray();
for(int i=0; i<N; i++) {
play(inputs[i]);
}
// 명령 끝난 후 탱크 위치 저장
if(tank.dir=='u') map[tank.r][tank.c] = '^';
else if(tank.dir=='d') map[tank.r][tank.c] = 'v';
else if(tank.dir=='l') map[tank.r][tank.c] = '<';
else if(tank.dir=='r') map[tank.r][tank.c] = '>';
sb.append("#").append(t).append(" ");
for(int i=0; i<R; i++) {
for(int j=0; j<C; j++) {
sb.append(map[i][j]);
}
sb.append("\\n");
}
}
System.out.println(sb.toString());
br.close();
}
static void play(char order) {
if(order == 'S') shoot();
else move(order);
}
// 전차 이동
static void move(char order) {
map[tank.r][tank.c] = '.';
if(order == 'U') {
tank.dir = 'u';
if(0<=tank.r-1 && map[tank.r-1][tank.c]=='.') tank.r-=1;
}
else if(order == 'D') {
tank.dir = 'd';
if(tank.r+1<R && map[tank.r+1][tank.c]=='.') tank.r+=1;
}
else if(order == 'L') {
tank.dir = 'l';
if(0<=tank.c-1 && map[tank.r][tank.c-1]=='.') tank.c-=1;
}
else {
tank.dir = 'r';
if(tank.c+1<C && map[tank.r][tank.c+1]=='.') tank.c +=1;
}
}
// 벽에 부딪히거나 맵 밖으로 나갈 때까지 직진
static void shoot() {
// 위쪽으로 발사
if(tank.dir == 'u') {
int bomb=tank.r;
while(true) {
if(bomb<0 || map[bomb][tank.c]=='*' || map[bomb][tank.c]=='#') {
if(0<=bomb && map[bomb][tank.c]=='*') map[bomb][tank.c]='.';
break;
}
bomb--;
}
}
// 아래쪽으로 발사
else if(tank.dir == 'd') {
int bomb=tank.r;
while(true) {
if(bomb>=R || map[bomb][tank.c]=='*' || map[bomb][tank.c]=='#') {
if(bomb<R && map[bomb][tank.c]=='*') map[bomb][tank.c]='.';
break;
}
bomb++;
}
}
// 왼쪽으로 발사
else if(tank.dir == 'l') {
int bomb=tank.c;
while(true) {
if(bomb<0 || map[tank.r][bomb]=='*' || map[tank.r][bomb]=='#') {
if(0<=bomb && map[tank.r][bomb]=='*') map[tank.r][bomb]='.';
break;
}
bomb--;
}
}
// 오른쪽으로 발사
else {
int bomb=tank.c;
while(true) {
if(bomb>=C || map[tank.r][bomb]=='*' || map[tank.r][bomb]=='#') {
if(bomb<C && map[tank.r][bomb]=='*') map[tank.r][bomb]='.';
break;
}
bomb++;
}
}
}
}
'알고리즘 문제풀이 > SW Expert' 카테고리의 다른 글
[SW Expert 1953] 탈주범 검거 (0) | 2023.04.04 |
---|---|
[SW Expert 5656] 벽돌 깨기 (0) | 2023.02.25 |
[SW 1247] 최적 경로 (0) | 2023.02.23 |
[SW Expert 5215] 햄버거 다이어트 (0) | 2023.02.16 |
[SW Expert 4012] 요리사 (2) | 2023.02.16 |
댓글