링크

https://www.acmicpc.net/problem/14503

 

문제

 

풀이

그냥 쓰여있는 문제를 구현하면 되는 문제.

조건에 따라 수행하는 액션에 대해 집중하고 구현하면 된다.

코드

import sys

N, M = map(int, input().split())
r, c, d = map(int, input().split())

arr = []
visit = [[0] * M for _ in range(N)]

for _ in range(N):
    arr.append(list(map(int, sys.stdin.readline().strip().split())))

#북, 동, 남, 서
moves = [[-1, 0], [0, 1], [1, 0], [0, -1]]
turn_count = 0
ans = 1

visit[r][c] = 1

while True:
    d = (d + 3) % 4
    nr = r + moves[d][0]
    nc = c + moves[d][1]

    if nr >= N or nc >= M or nr < 0 or nc < 0:
        turn_count += 1
        continue

    if arr[nr][nc] == 0 and visit[nr][nc] == 0:
        visit[nr][nc] = 1
        r = nr
        c = nc
        turn_count = 0
        ans += 1
        continue

    else:
        turn_count += 1

    if turn_count == 4:
        nr = r - moves[d][0]
        nc = c - moves[d][1]

        if nr >= N or nc >= M or nr < 0 or nc < 0:
            break

        elif arr[nr][nc] == 0:
            r = nr
            c = nc
            turn_count = 0
        else:
            break


print(ans)

 

후기

너무 코드가 지저분한 것 같아서 다른 분들의 코드를 봤는데 다른 분들의 풀이를 보니

필요 없는 코드가 많아서 수정하다보니 아래와 같은 코드가 나왔다.

import sys

N, M = map(int, input().split())
r, c, d = map(int, input().split())

arr = []
visit = [[0] * M for _ in range(N)]

for _ in range(N):
    arr.append(list(map(int, sys.stdin.readline().strip().split())))

#북, 동, 남, 서
moves = [[-1, 0], [0, 1], [1, 0], [0, -1]]
turn_count = 0
ans = 1

visit[r][c] = 1

while True:
    d = (d + 3) % 4
    nr = r + moves[d][0]
    nc = c + moves[d][1]

    if arr[nr][nc] == 0 and visit[nr][nc] == 0:
        visit[nr][nc] = 1
        r = nr
        c = nc
        turn_count = 0
        ans += 1
        continue

    else:
        turn_count += 1

    if turn_count == 4:
        nr = r - moves[d][0]
        nc = c - moves[d][1]

        if arr[nr][nc] == 0:
            r = nr
            c = nc
            turn_count = 0
        else:
            break


print(ans)

나는 index가 넘어가서 생기는 에러를 발생하기 위해서 예외처리를 해주었는데, 

위 코드는 그런거 없이 넘어갔다. 

원래대로라면 nr, nc를 더하는 과정에서 배열을 넘어가는 것을 조회하게 되지 않나..?

라고 생각해서 그냥 테스트로 print에 넘어가는 배열 조회해봤는데 (이하생략)

3 3

1 1 0

1 1 1

1 0 1

1 0 1

하면 분명 통과된 코드도 index 에러 나서 뭐지.. 싶었는데,

문제에

요걸 못봤다.

구현 문제는 문제를 꼭 잘 읽도록하자.

링크

https://www.acmicpc.net/problem/7569

 

7569번: 토마토

첫 줄에는 상자의 크기를 나타내는 두 정수 M,N과 쌓아올려지는 상자의 수를 나타내는 H가 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M ≤ 100, 2 ≤ N ≤ 100,

www.acmicpc.net

 

문제

 

 

풀이

1. 토마토의 정보를 담을 배열 하나, 걸리는 시간을 담을 배열 하나해서 총 두개의 3차원 배열을 만들어준다.

2. 반복문을 통해 배열을 받아준다.

2-1. 입력을 보면, 한판을 다 받고 다음판을 받기 때문에 반복문을 배치할 때, H를 가장 밖에 둔다.

3. 배열에 있는 숫자가 1, 즉 익은 토마토일 때 시간을 나태내는 배열에 1을 넣으며, 더불어 queue에 넣고 bfs를 할 준비를 한다.

4. queue에 넣은 숫자들을 하나씩 꺼내고, 인접한 부분을 모두 탐색시킨다.

5. 3차원 배열이므로, h값 즉 zindex가 바뀌는 경우를 고려하여 추가한다.

6. 탐색을 진행하면서 안익은 토마토를 만났고, 해당 부분의 걸리는 시간이 0으로 아직 변경되지 않았을 때, 이동하기 전 토마토의 시간 + 1 값을 저장한다.

7. 탐색을 진행한 후, 다시 배열들의 탐색을 진행한다.

8. 토마토를 전부 익힐 수 있는지에 대한 여부를 판단하는 boolean 변수를 만들어 준다,.

9. 반복문을 통해 배열을 탐색하면서 토마토가 존재하는 경우(!= -1)인데 걸리는 시간이 0인 경우, 탐색이 진행되지 않은 것으로 판단하여,

설정한 boolean변수를 false로 바꾸고 break한다.

10. 그게 아니라면 계속 탐색을 진행해서 가장 큰 값을 정답으로 설정한다.

 

코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
    static int x = 0,y = 0,z = 0;
    static int[] dz = {-1,0,0,0,0,1};
    static int[] dy = {0,1,0,-1,0,0};
    static int[] dx = {0,0,1,0,-1,0};

    static Queue<Integer[]> queue = new LinkedList<>();
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        x = Integer.parseInt(st.nextToken());
        y = Integer.parseInt(st.nextToken());
        z = Integer.parseInt(st.nextToken());

        // 입력 index
        int[][][] arr = new int[z][y][x];
        int[][][] dist = new int[z][y][x];

        for(int i = 0; i<z; i++){
            for(int j = 0; j<y; j++){
                st = new StringTokenizer(br.readLine());
                for(int k = 0; k<x; k++){
                    int num = Integer.parseInt(st.nextToken());
                    arr[i][j][k] = num;
                    if(num == 1){
                        dist[i][j][k] = 1;
                        queue.offer(new Integer[]{i,j,k});
                    }
                }
            }
        }
        int ans = 0;

        while(!queue.isEmpty()){
            Integer[] tmp = queue.poll();

            int tmpz = tmp[0];
            int tmpy = tmp[1];
            int tmpx = tmp[2];

            for(int i = 0; i<dz.length; i++){
                int nz = tmpz + dz[i];
                int ny = tmpy + dy[i];
                int nx = tmpx + dx[i];

                if(nz < 0 || ny < 0 || nx <0 || nz >= z || ny >= y || nx >= x){
                    continue;
                }
                if(arr[nz][ny][nx] == 0 && dist[nz][ny][nx] == 0){
                    dist[nz][ny][nx] = dist[tmpz][tmpy][tmpx] + 1;
                    queue.offer(new Integer[] {nz,ny,nx});
                }
            }
        }

        boolean possible = true;

        for(int i = 0; i<z; i++){
            if (!possible) {
                ans = 0;
                break;
            }
            for(int j = 0;  j<y; j++){
                for(int k = 0; k<x; k++){
                    if (!possible) {
                        ans = 0;
                        break;
                    }
                    if(arr[i][j][k] != -1&&dist[i][j][k] == 0) {
                        possible = false;
                        if (!possible) {
                            ans = 0;
                            break;
                        }
                    }
                    ans = Math.max(ans, dist[i][j][k]);
                }
            }
        }
        System.out.println(ans-1);
    }

    }

 

후기

3차원 배열 탐색할 때, 처음에 zindex를 -1로 옮기고 xy도 같이 옮겨버려서 답이 안나왔음.

처음에 bfs 메소드로 만들고 싶어서 static 선언했는데, 중간에 수업 듣느라 까먹어서 dx dy dz static 해놓은 것도 까먹음

다음번엔 메소드 단위로 짤라서 만들어보고 싶음

다음엔 주석을 좀 써볼까 고민 중

+ Recent posts