문제 - https://www.acmicpc.net/problem/17406

 

17406번: 배열 돌리기 4

크기가 N×M 크기인 배열 A가 있을때, 배열 A의 값은 각 행에 있는 모든 수의 합 중 최솟값을 의미한다. 배열 A가 아래와 같은 경우 1행의 합은 6, 2행의 합은 4, 3행의 합은 15이다. 따라서, 배열 A의

www.acmicpc.net

import java.util.*;
import java.io.*;

public class Main {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static StringTokenizer st;

    static int N, M, K, min = Integer.MAX_VALUE;
    static int[][] arr, info, copy, tmp;
    static boolean[] picked;
    static Stack<Integer> jobq = new Stack<>();

    public static void main(String[] args) throws IOException{

        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());

        arr = new int[N][M];
        copy = new int[N][M];
        tmp = new int[N][M];
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < M; j++) {
                arr[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        info = new int[K][3];
        for (int i = 0; i < K; i++) {
            st = new StringTokenizer(br.readLine());
            info[i][0] = Integer.parseInt(st.nextToken())-1;
            info[i][1] = Integer.parseInt(st.nextToken())-1;
            info[i][2] = Integer.parseInt(st.nextToken());
        }

        picked = new boolean[K];
        pick(K);

        bw.write(min+"\n");

        bw.flush();
        bw.close();
        br.close();
    }

    static void pick(int remain){
        if(remain==0){
            calc();
            return;
        }
        for (int i = 0; i < K; i++) {
            if(!picked[i]){
                picked[i] = true;
                jobq.add(i);
                pick(remain-1);
                jobq.pop();
                picked[i] = false;
            }
        }
    }
    static void calc() {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                copy[i][j] = arr[i][j];
            }
        }

        for(Integer i : jobq){
            rotate(info[i][0], info[i][1], info[i][2]);
        }

        for (int i = 0; i < N; i++) {
            int sum = 0;
            for (int j = 0; j < M; j++) {
                sum += copy[i][j];
            }
            min = Math.min(min, sum);
        }
    }
    static void rotate(int r, int c, int s){
        if(s==0) return;

        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                tmp[i][j] = copy[i][j];
            }
        }

        for (int i = 0; i < 2*s; i++) {
            copy[r-s][c-s+i+1] = tmp[r-s][c-s+i];
        }
        for (int i = 0; i < 2*s; i++) {
            copy[r-s+i+1][c+s] = tmp[r-s+i][c+s];
        }
        for (int i = 0; i < 2*s; i++) {
            copy[r+s][c+s-i-1] = tmp[r+s][c+s-i];
        }
        for (int i = 0; i < 2*s; i++) {
            copy[r+s-i-1][c-s] = tmp[r+s-i][c-s];
        }

        rotate(r, c, s-1);
    }
}

 

 

단순 구현문제 같으면서도 생각보다 퍼포먼스가 나오지않는걸 보니 뭔가 알고리즘 최적화가 필요한 것 같다...ㅠㅠ

'공부 > algorithm' 카테고리의 다른 글

BOJ N번째 큰 수(2075) - Java  (0) 2021.12.23
BOJ 토마토(7576) - Java  (0) 2021.12.20
BOJ 연구소 3(17142) - Java  (0) 2021.11.18
BOJ 빙산(2573) - Java  (0) 2021.11.18
BOJ 나무 재테크(16235) - Java  (0) 2021.11.17

문제 - https://www.acmicpc.net/problem/2075

 

2075번: N번째 큰 수

첫째 줄에 N(1 ≤ N ≤ 1,500)이 주어진다. 다음 N개의 줄에는 각 줄마다 N개의 수가 주어진다. 표에 적힌 수는 -10억보다 크거나 같고, 10억보다 작거나 같은 정수이다.

www.acmicpc.net

import java.io.*;
import java.util.*;

public class Main {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static StringTokenizer st;

    static int N;
    static PriorityQueue<Integer> pq = new PriorityQueue<>();

    public static void main(String[] args) throws IOException {

        N = Integer.parseInt(br.readLine());
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < N; j++) {
                pq.add(-Integer.parseInt(st.nextToken()));
            }
        }

        for (int i = 0; i < N; i++) {
            int answer = pq.poll();
        }
        bw.write(-answer+"\n");

        br.close();
        bw.flush();
        bw.close();
    }
}

크게 어려움은 없었던 PQ를 이용한 문제였다. 다만.. Java15버전에서는 메모리초과가 났다. PQ를 사용하지 않고 푸는 방법이 권장되는걸까??

'공부 > algorithm' 카테고리의 다른 글

BOJ 배열 돌리기 4(17406) - Java  (0) 2022.01.29
BOJ 토마토(7576) - Java  (0) 2021.12.20
BOJ 연구소 3(17142) - Java  (0) 2021.11.18
BOJ 빙산(2573) - Java  (0) 2021.11.18
BOJ 나무 재테크(16235) - Java  (0) 2021.11.17

문제 - https://www.acmicpc.net/problem/7576

 

7576번: 토마토

첫 줄에는 상자의 크기를 나타내는 두 정수 M,N이 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M,N ≤ 1,000 이다. 둘째 줄부터는 하나의 상자에 저장된 토마토

www.acmicpc.net

import java.io.*;
import java.util.*;

public class Main {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static StringTokenizer st;

    static boolean done = false;
    static boolean[][] already;
    static int N, M, D = -1;
    static int[] dr = {-1, 0, 1, 0};
    static int[] dc = {0, 1, 0, -1};
    static int[][] arr;
    static class Pos{
        int r, c;
        public Pos(int r, int c){
            this.r = r;
            this.c = c;
        }
    }
    static ArrayList<Pos> pre, post;

    public static void main(String[] args) throws IOException {

        st = new StringTokenizer(br.readLine());
        M = Integer.parseInt(st.nextToken());
        N = Integer.parseInt(st.nextToken());

        arr = new int[N][M];
        already = new boolean[N][M];
        pre = new ArrayList<>();
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < M; j++) {
                arr[i][j] = Integer.parseInt(st.nextToken());
                if (arr[i][j] == 1) pre.add(new Pos(i, j));
            }
        }

        while(!done){
            check();
            flow();
            if(pre.isEmpty() && !done){
                D = -1;
                break;
            }
            D++;
        }
        bw.write(D+"\n");

        br.close();
        bw.flush();
        bw.close();
    }
    static void check(){
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                if (arr[i][j] == 0) return;
            }
        }
        done = true;
    }
    static void flow(){
        post = new ArrayList<>();
        for(Pos point : pre){
            int r = point.r;
            int c = point.c;
            already[r][c] = true;
            for (int w = 0; w < 4; w++) {
                int nr = r + dr[w];
                int nc = c + dc[w];
                if (0<=nr && nr<N && 0<=nc && nc<M && arr[nr][nc]==0 && !already[nr][nc]){
                    arr[nr][nc] = 1;
                    post.add(new Pos(nr, nc));
                    already[nr][nc] = true;
                }
            }
        }
        pre = post;
    }
}

입사 후 처음으로 시간을 내서 문제를 풀어봤는데... 쉬운 문제임에도 불구하고 뭔가 코드가 낯설게 느껴졌다. 다시금 PS에서는 꾸준함이 중요하다는걸 느끼는 순간이었다. 바빠도 꾸준히 풀어보려고 노력해야겠다!

'공부 > algorithm' 카테고리의 다른 글

BOJ 배열 돌리기 4(17406) - Java  (0) 2022.01.29
BOJ N번째 큰 수(2075) - Java  (0) 2021.12.23
BOJ 연구소 3(17142) - Java  (0) 2021.11.18
BOJ 빙산(2573) - Java  (0) 2021.11.18
BOJ 나무 재테크(16235) - Java  (0) 2021.11.17

문제 - https://www.acmicpc.net/problem/17142

 

17142번: 연구소 3

인체에 치명적인 바이러스를 연구하던 연구소에 승원이가 침입했고, 바이러스를 유출하려고 한다. 바이러스는 활성 상태와 비활성 상태가 있다. 가장 처음에 모든 바이러스는 비활성 상태이고

www.acmicpc.net

import java.io.*;
import java.util.*;

public class Main {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static StringTokenizer st;

    static final int MAX = 5000;
    static int N, M, T = MAX;
    static int[] dr = {-1, 0, 1, 0};
    static int[] dc = {0, 1, 0, -1};
    static int[][] map, copy;
    static class Point{
        int r, c;
        public Point(int r, int c){
            this.r = r;
            this.c = c;
        }
    }
    static ArrayList<Point> virus = new ArrayList<>();
    static Queue<Point> Q;

    public static void main(String[] args) throws Exception {
        
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());

        map = new int[N][N];
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < N; j++) {
                int type = Integer.parseInt(st.nextToken());
                if (type==2) virus.add(new Point(i, j));
                map[i][j] = type==1 ? -1 : MAX;
            }
        }
        
        pick(0, M);

        bw.write(T < MAX ? T+"\n" : "-1\n");
        bw.flush();
        bw.close();
        br.close();
    }
    static void pick(int cur, int remain){
        if (remain==0){
            spread();
            calc();
            return;
        }

        for (int i = cur; i < virus.size()-remain+1; i++) {
            Point now = virus.get(i);
            map[now.r][now.c] = 0;
            pick(i+1, remain-1);
            map[now.r][now.c] = MAX;
        }
    }
    static void spread(){
        Q = new ArrayDeque<>();
        copy = new int[N][N];
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                copy[i][j] = map[i][j];
                if(copy[i][j]==0) Q.add(new Point(i, j));
            }
        }

        while(!Q.isEmpty()){
            Point cur = Q.poll();
            for (int w = 0; w < 4; w++) {
                int nr = cur.r + dr[w];
                int nc = cur.c + dc[w];
                if(0<=nr && nr<N && 0<=nc && nc<N && copy[nr][nc]==MAX){
                    copy[nr][nc] = copy[cur.r][cur.c] + 1;
                    Q.add(new Point(nr, nc));
                }
            }
        }
    }
    static void calc(){
        for (Point v : virus){
            copy[v.r][v.c] = 0;
        }
        int tmp = 0;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                tmp = Math.max(tmp, copy[i][j]);
            }
        }
        T = Math.min(T, tmp);
    }
}

이미 존재하는 바이러스에 대한 예외처리가 관건인 문제였다.

그 외에는 단순한 BFS로 확산처리를 해주면 크게 걸림돌은 없었다.

'공부 > algorithm' 카테고리의 다른 글

BOJ N번째 큰 수(2075) - Java  (0) 2021.12.23
BOJ 토마토(7576) - Java  (0) 2021.12.20
BOJ 빙산(2573) - Java  (0) 2021.11.18
BOJ 나무 재테크(16235) - Java  (0) 2021.11.17
BOJ 치즈(2636) - Java  (0) 2021.11.16

문제 - https://www.acmicpc.net/problem/2573

 

2573번: 빙산

첫 줄에는 이차원 배열의 행의 개수와 열의 개수를 나타내는 두 정수 N과 M이 한 개의 빈칸을 사이에 두고 주어진다. N과 M은 3 이상 300 이하이다. 그 다음 N개의 줄에는 각 줄마다 배열의 각 행을

www.acmicpc.net

import java.io.*;
import java.util.*;

public class Main {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static StringTokenizer st;

    static int N, M, Y = 0, mass = 1;
    static int[] dr = {-1, 0, 1, 0};
    static int[] dc = {0, 1, 0, -1};
    static int[][] map;
    static class Point{
        int r, c;
        public Point(int r, int c){
            this.r = r;
            this.c = c;
        }
    }
    static boolean[][] visit;
    static Queue<Point> Q;

    public static void main(String[] args) throws Exception {

        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        map = new int[N][M];
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < M; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        while(mass==1){
            Y++;
            melt();
            split_check();
        }

        bw.write(mass>1 ? Y+"\n" : "0\n");
        bw.flush();
        bw.close();
        br.close();
    }
    static void melt(){
        int[][] tmp = new int[N][M];
        for (int i = 1; i < N-1; i++) {
            for (int j = 1; j < M-1; j++) {
                if (map[i][j]<=0) continue;
                int cnt = 0;
                for (int w = 0; w < 4; w++) {
                    int nr = i + dr[w];
                    int nc = j + dc[w];
                    if(map[nr][nc]<=0) cnt++;
                }
                tmp[i][j] -= cnt;
            }
        }

        for (int i = 1; i < N-1; i++) {
            for (int j = 1; j < M-1; j++) {
                map[i][j] += tmp[i][j];
            }
        }
    }
    static void split_check(){
        mass = 0;
        visit = new boolean[N][M];

        for (int i = 1; i < N-1; i++) {
            for (int j = 1; j < M-1; j++) {
                if (map[i][j]>0 && !visit[i][j]){
                    mass++;
                    bfs(i, j);
                }
            }
        }
    }
    static void bfs(int i, int j){
        Q = new ArrayDeque<>();
        Q.add(new Point(i, j));
        visit[i][j] = true;

        while(!Q.isEmpty()){
            Point cur = Q.poll();
            for (int w = 0; w < 4; w++) {
                int nr = cur.r + dr[w];
                int nc = cur.c + dc[w];
                if (map[nr][nc]>0 && !visit[nr][nc]){
                    Q.add(new Point(nr, nc));
                    visit[nr][nc] = true;
                }
            }
        }
    }
}

BFS를 이용한 단순한 구현문제였다.

풀이가 간단해서 런타임은 크게 차이없을것이라 생각했는데.. 생각보다 상위권 제출자와 꽤나 차이가 나서 당황했다..

 

'공부 > algorithm' 카테고리의 다른 글

BOJ 토마토(7576) - Java  (0) 2021.12.20
BOJ 연구소 3(17142) - Java  (0) 2021.11.18
BOJ 나무 재테크(16235) - Java  (0) 2021.11.17
BOJ 치즈(2636) - Java  (0) 2021.11.16
BOJ 연구소 2(17141) - Java  (0) 2021.11.16

문제 - https://www.acmicpc.net/problem/16235

 

16235번: 나무 재테크

부동산 투자로 억대의 돈을 번 상도는 최근 N×N 크기의 땅을 구매했다. 상도는 손쉬운 땅 관리를 위해 땅을 1×1 크기의 칸으로 나누어 놓았다. 각각의 칸은 (r, c)로 나타내며, r은 가장 위에서부터

www.acmicpc.net

import java.io.*;
import java.util.*;

public class Main {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static StringTokenizer st;

    static int N, M, K;
    static int[] dr = {-1, -1, 0, 1, 1, 1, 0, -1};
    static int[] dc = {0, 1, 1, 1, 0, -1, -1, -1};
    static int[][] A;
    static class Area{
        int hp;
        ArrayList<Integer> live;
        Queue<Integer> dead;
        public Area(){
            this.hp = 5;
            live = new ArrayList<>();
            dead = new ArrayDeque<>();
        }
    }
    static Area[][] areas;

    public static void main(String[] args) throws Exception {

        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());

        areas = new Area[N][N];
        A = new int[N][N];
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < N; j++) {
                A[i][j] = Integer.parseInt(st.nextToken());
                areas[i][j] = new Area();
            }
        }
        for (int i = 0; i < M; i++) {
            st = new StringTokenizer(br.readLine());
            int x = Integer.parseInt(st.nextToken());
            int y = Integer.parseInt(st.nextToken());
            int z = Integer.parseInt(st.nextToken());
            areas[x-1][y-1].live.add(z);
        }
        for (int i = 0; i < K; i++) {
            spring();
            summer();
            autumn();
            winter();
        }

        bw.write(calc()+"\n");
        bw.flush();
        bw.close();
        br.close();
    }
    static void spring(){
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                int live = areas[i][j].live.size();
                if (live > 1) Collections.sort(areas[i][j].live);
                for (int k = 0; k < areas[i][j].live.size(); k++) {
                    int age = areas[i][j].live.get(k);
                    if(areas[i][j].hp >= age){
                        areas[i][j].hp -= age;
                        areas[i][j].live.set(k, age+1);
                    }
                    else{
                        for (int l = k; l < live; l++) {
                            areas[i][j].dead.add(areas[i][j].live.remove(k));
                        }
                        break;
                    }
                }
            }
        }
    }
    static void summer(){
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                while(!areas[i][j].dead.isEmpty()){
                    areas[i][j].hp += areas[i][j].dead.poll()/2;
                }
            }
        }
    }
    static void autumn(){
        for (int r = 0; r < N; r++) {
            for (int c = 0; c < N; c++) {
                for (int age : areas[r][c].live){
                    if (age%5 == 0){
                        for (int w = 0; w < 8; w++) {
                            int nr = r + dr[w];
                            int nc = c + dc[w];
                            if (0<=nr && nr<N && 0<=nc && nc<N) areas[nr][nc].live.add(1);
                        }
                    }
                }
            }
        }
    }
    static void winter(){
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                areas[i][j].hp += A[i][j];
            }
        }
    }
    static int calc(){
        int cnt = 0;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                cnt += areas[i][j].live.size();
            }
        }
        return cnt;
    }
}

크게 어렵지않았던 단순한 구현문제이지만 퍼포먼스가 좋지는 못한 코드이다.

그러나 가장 직관적으로 구현했다고 생각한다!

추가로 이 문제를 풀면서 배운것은, Java에서 반복문의 횟수에 배열의 길이를 명시했을시, 반복문을 돌며 배열의 길이가 달라지면 실시간으로 반영된다!

'공부 > algorithm' 카테고리의 다른 글

BOJ 연구소 3(17142) - Java  (0) 2021.11.18
BOJ 빙산(2573) - Java  (0) 2021.11.18
BOJ 치즈(2636) - Java  (0) 2021.11.16
BOJ 연구소 2(17141) - Java  (0) 2021.11.16
BOJ 최종 순위(3665) - Java  (0) 2021.11.16

문제 - https://www.acmicpc.net/problem/2636

 

2636번: 치즈

아래 <그림 1>과 같이 정사각형 칸들로 이루어진 사각형 모양의 판이 있고, 그 위에 얇은 치즈(회색으로 표시된 부분)가 놓여 있다. 판의 가장자리(<그림 1>에서 네모 칸에 X친 부분)에는 치즈가 놓

www.acmicpc.net

import java.io.*;
import java.util.*;

public class Main {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static StringTokenizer st;

    static int R, C, T = 0, pred = 0, remain = 0;
    static int[] dr = {-1, 0, 1, 0};
    static int[] dc = {0, 1, 0, -1};
    static int[][] map;
    static class Point{
        int r, c;
        public Point(int r, int c){
            this.r = r;
            this.c = c;
        }
    }

    public static void main(String[] args) throws Exception {

        st = new StringTokenizer(br.readLine());
        R = Integer.parseInt(st.nextToken());
        C = Integer.parseInt(st.nextToken());
        map = new int[R][C];
        for (int i = 0; i < R; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < C; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        do {
            remain = melt();
            pred = predict();
            T++;
        }while(remain > pred);

        bw.write(T+"\n"+remain+"\n");
        bw.flush();
        bw.close();
        br.close();
    }
    static int predict(){
        boolean[][] visit = new boolean[R][C];
        Queue<Point> Q = new ArrayDeque<>();
        Q.add(new Point(0, 0));
        visit[0][0] = true;
        int tmp = 0;

        while(!Q.isEmpty()){
            Point cur = Q.poll();
            for (int i = 0; i < 4; i++) {
                int nr = cur.r + dr[i];
                int nc = cur.c + dc[i];
                if(0<=nr && nr<R && 0<=nc && nc<C && !visit[nr][nc]){
                    visit[nr][nc] = true;
                    if(map[nr][nc]==0) Q.add(new Point(nr, nc));
                    else if(map[nr][nc]==1){
                        map[nr][nc] = 2;
                        tmp++;
                    }
                }
            }
        }
        return tmp;
    }
    static int melt(){
        int tmp = 0;
        for (int i = 0; i < R; i++) {
            for (int j = 0; j < C; j++) {
                if (map[i][j]==2) map[i][j] = 0;
                else if (map[i][j]==1) tmp++;
            }
        }
        return tmp;
    }
}

 

 

단순한 BFS를 이용한 풀이지만 재밌는 문제였다.

'공부 > algorithm' 카테고리의 다른 글

BOJ 빙산(2573) - Java  (0) 2021.11.18
BOJ 나무 재테크(16235) - Java  (0) 2021.11.17
BOJ 연구소 2(17141) - Java  (0) 2021.11.16
BOJ 최종 순위(3665) - Java  (0) 2021.11.16
BOJ 회의실 배정(1931) - Java  (0) 2021.10.25

문제 - https://www.acmicpc.net/problem/17141

 

17141번: 연구소 2

인체에 치명적인 바이러스를 연구하던 연구소에 승원이가 침입했고, 바이러스를 유출하려고 한다. 승원이는 연구소의 특정 위치에 바이러스 M개를 놓을 것이고, 승원이의 신호와 동시에 바이

www.acmicpc.net

import java.io.*;
import java.util.*;

public class Main {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static StringTokenizer st;

    static int N, M, MaxTime = Integer.MAX_VALUE;
    static int[] dr = {-1, 0, 1, 0};
    static int[] dc = {0, 1, 0, -1};
    static int[][] map, copy;
    static class Pos{
        int r, c;
        public Pos(int r, int c){
            this.r = r;
            this.c = c;
        }
    }
    static ArrayList<Pos> virus = new ArrayList<>();
    static Queue<Pos> Q;

    public static void main(String[] args) throws Exception {

        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        map = new int[N][N];
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < N; j++) {
                int type = Integer.parseInt(st.nextToken());
                map[i][j] = Integer.MAX_VALUE;
                if (type==1) map[i][j] = -1;
                else if (type==2) virus.add(new Pos(i, j));
            }
        }
        pick(0, M);

        bw.write(MaxTime<Integer.MAX_VALUE ? MaxTime+"\n" : "-1\n");
        bw.flush();
        bw.close();
        br.close();
    }
    static void pick(int cur, int remain){
        if (remain==0){
            spread();
            MaxTime = Math.min(MaxTime, calc());
            return;
        }
        for (int i = cur; i < virus.size()-remain+1; i++) {
            Pos p = virus.get(i);
            map[p.r][p.c] = 0;
            pick(i+1, remain-1);
            map[p.r][p.c] = Integer.MAX_VALUE;
        }
    }
    static void spread(){
        Q = new ArrayDeque<>();
        copy = new int[N][N];
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                copy[i][j] = map[i][j];
                if (map[i][j]==0) Q.add(new Pos(i, j));
            }
        }

        while(!Q.isEmpty()){
            Pos cur = Q.poll();
            for (int w = 0; w < 4; w++) {
                int nr = cur.r + dr[w];
                int nc = cur.c + dc[w];
                if(0<=nr && nr<N && 0<=nc && nc<N && copy[nr][nc]==Integer.MAX_VALUE){
                    copy[nr][nc] = copy[cur.r][cur.c] + 1;
                    Q.add(new Pos(nr, nc));
                }
            }
        }
    }
    static int calc(){
        int tmp = 0;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (copy[i][j]<0) continue;
                if (copy[i][j]==Integer.MAX_VALUE) return Integer.MAX_VALUE;
                tmp = Math.max(tmp, copy[i][j]);
            }
        }
        return tmp;
    }
}

간단한 BFS문제였으나 처음부터 최적화 욕심내다가 오히려 더 빙빙돌아서 풀었다..

첫 제출은 무식하더라도 정확하게 구현하고, 그 다음 최적화를 하는 방향으로 풀이하자!

'공부 > algorithm' 카테고리의 다른 글

BOJ 나무 재테크(16235) - Java  (0) 2021.11.17
BOJ 치즈(2636) - Java  (0) 2021.11.16
BOJ 최종 순위(3665) - Java  (0) 2021.11.16
BOJ 회의실 배정(1931) - Java  (0) 2021.10.25
BOJ 쉬운 계단 수(10844) - Java  (0) 2021.10.23

+ Recent posts