코드굽는 타자기

SWEA[1873] - 상호의 배틀필드[D3] 본문

알고리즘/Simulation

SWEA[1873] - 상호의 배틀필드[D3]

bright-jun 2020. 2. 12. 10:02

링크

문제설명

  • 시뮬

문제풀이

  • 시뮬

문제코드

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Solution {
    public static int[][] dir = {
            {-1,0},      //U
            {1,0},    //D
            {0,-1},   //L
            {0,1},    //R
    };
    public static int H;
    public static int W;
    public static int r;
    public static int c;
    public static char[][] map;
    /*
.    평지(전차가 들어갈 수 있다.)
*    벽돌로 만들어진 벽
#    강철로 만들어진 벽
-    물(전차는 들어갈 수 없다.)
^    위쪽을 바라보는 전차(아래는 평지이다.)
v    아래쪽을 바라보는 전차(아래는 평지이다.)
<    왼쪽을 바라보는 전차(아래는 평지이다.)
>    오른쪽을 바라보는 전차(아래는 평지이다.)
     */
    public static void move(char next_dir) {
        int nr=0;
        int nc=0;
        char temp;
        switch (next_dir) {
        case 'U':
            map[r][c] = '^';
            nr = r+dir[0][0];
            nc = c+dir[0][1];
//            경계 안이고, 다음칸이 평지일 경우
            if(nr>=0 && nr<H && nc>=0 && nc<W && map[nr][nc]=='.') {
                temp = map[r][c];
                map[nr][nc]=temp;
                map[r][c]='.';
                r=nr;
                c=nc;
            }
            break;
        case 'D':
            map[r][c] = 'v';
            nr = r+dir[1][0];
            nc = c+dir[1][1];
//            경계 안이고, 다음칸이 평지일 경우
            if(nr>=0 && nr<H && nc>=0 && nc<W && map[nr][nc]=='.') {
                temp = map[r][c];
                map[nr][nc]=temp;
                map[r][c]='.';
                r=nr;
                c=nc;
            }
            break;
        case 'L':
            map[r][c] = '<';
            nr = r+dir[2][0];
            nc = c+dir[2][1];
//            경계 안이고, 다음칸이 평지일 경우
            if(nr>=0 && nr<H && nc>=0 && nc<W && map[nr][nc]=='.') {
                temp = map[r][c];
                map[nr][nc]=temp;
                map[r][c]='.';
                r=nr;
                c=nc;
            }
            break;
        case 'R':
            map[r][c] = '>';
            nr = r+dir[3][0];
            nc = c+dir[3][1];
//            경계 안이고, 다음칸이 평지일 경우
            if(nr>=0 && nr<H && nc>=0 && nc<W && map[nr][nc]=='.') {
                temp = map[r][c];
                map[nr][nc]=temp;
                map[r][c]='.';
                r=nr;
                c=nc;
            }
            break;
        case 'S':
            shoot(map[r][c]);
            break;

        default:
            break;
        }
    }

    public static void shoot(char now_dir) {
        int nr=0;
        int nc=0;
        int sr=r;
        int sc=c;
        switch (now_dir) {
        case '^':
            while(true) {
                nr = sr+dir[0][0];
                nc = sc+dir[0][1];
//                경계 안이고
                if(nr>=0 && nr<H && nc>=0 && nc<W) {
//                    벽돌을 만나면 부수고 터짐 끝
                    if(map[nr][nc]=='*'){
                        map[nr][nc]='.';
                        break;
                    }
//                    강철을 만나면 터짐 끝
                    else if(map[nr][nc]=='#') {
                        break;
                    }
//                    그냥 지나감
                    else {
                        sr=nr;
                        sc=nc;
                    }
                }
//                경계 밖으로 나가면 끝
                else {
                    break;
                }
            }
            break;
        case 'v':
            while(true) {
                nr = sr+dir[1][0];
                nc = sc+dir[1][1];
//                경계 안이고
                if(nr>=0 && nr<H && nc>=0 && nc<W) {
//                    벽돌을 만나면 부수고 터짐 끝
                    if(map[nr][nc]=='*'){
                        map[nr][nc]='.';
                        break;
                    }
//                    강철을 만나면 터짐 끝
                    else if(map[nr][nc]=='#') {
                        break;
                    }
//                    그냥 지나감
                    else {
                        sr=nr;
                        sc=nc;
                    }
                }
//                경계 밖으로 나가면 끝
                else {
                    break;
                }
            }
            break;
        case '<':
            while(true) {
                nr = sr+dir[2][0];
                nc = sc+dir[2][1];
//                경계 안이고
                if(nr>=0 && nr<H && nc>=0 && nc<W) {
//                    벽돌을 만나면 부수고 터짐 끝
                    if(map[nr][nc]=='*'){
                        map[nr][nc]='.';
                        break;
                    }
//                    강철을 만나면 터짐 끝
                    else if(map[nr][nc]=='#') {
                        break;
                    }
//                    그냥 지나감
                    else {
                        sr=nr;
                        sc=nc;
                    }
                }
//                경계 밖으로 나가면 끝
                else {
                    break;
                }
            }
            break;
        case '>':
            while(true) {
                nr = sr+dir[3][0];
                nc = sc+dir[3][1];
//                경계 안이고
                if(nr>=0 && nr<H && nc>=0 && nc<W) {
//                    벽돌을 만나면 부수고 터짐 끝
                    if(map[nr][nc]=='*'){
                        map[nr][nc]='.';
                        break;
                    }
//                    강철을 만나면 터짐 끝
                    else if(map[nr][nc]=='#') {
                        break;
                    }
//                    그냥 지나감
                    else {
                        sr=nr;
                        sc=nc;
                    }
                }
//                경계 밖으로 나가면 끝
                else {
                    break;
                }
            }
            break;

        default:
            break;
        }
    }

    public static void main(String[] args) throws NumberFormatException, IOException {
        //System.setIn(new FileInputStream("res/swea/1873_2.txt"));
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int T=Integer.parseInt(br.readLine());
        StringTokenizer st;
        for (int test_case = 1; test_case <= T; test_case++) {
            int ans=0;
//            입력
            st = new StringTokenizer(br.readLine());
            H = Integer.parseInt(st.nextToken());
            W = Integer.parseInt(st.nextToken());
            map = new char[H][W];

            for (int i = 0; i < H; i++) {
                map[i] = br.readLine().toCharArray();
            }

            int N = Integer.parseInt(br.readLine());
            char[] oper = new char[N];
            oper = br.readLine().toCharArray();

//            전차찾기
            top:
            for (int i = 0; i < H; i++) {
                for (int j = 0; j < W; j++) {
                    if(map[i][j]=='^' || map[i][j]=='v' || map[i][j]=='<' || map[i][j]=='>') {
                        r=i;
                        c=j;
                        break top;
                    }
                }
            }
//            수행

            for (int i = 0; i < N; i++) {
                move(oper[i]);
            }


            System.out.print("#"+test_case+" ");
            for (int i = 0; i < H; i++) {
                for (int j = 0; j < W; j++) {
                    System.out.print(map[i][j]);
                }
                System.out.println();
            }
            /*
             * 초기화
             */
        }//end test_case
    }//end main
}//end class

아쉬운점

  • 전역변수 업데이트를 제대로 안했음
    • 한칸 이동하면 r,c 값 업데이트 해야함
    • swap할 때, 배열을 넘기면 레퍼런스를 넘기기 때문에 char값을 선언해서 넘겨야 함.

잘한점

  • 전역변수 사용
Comments