๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Algorithm

[Java] 15686๋ฒˆ: ์น˜ํ‚จ ๋ฐฐ๋‹ฌ

๐ŸŒŽ Link : https://www.acmicpc.net/problem/15686

 

15686๋ฒˆ: ์น˜ํ‚จ ๋ฐฐ๋‹ฌ

ํฌ๊ธฐ๊ฐ€ N×N์ธ ๋„์‹œ๊ฐ€ ์žˆ๋‹ค. ๋„์‹œ๋Š” 1×1ํฌ๊ธฐ์˜ ์นธ์œผ๋กœ ๋‚˜๋ˆ„์–ด์ ธ ์žˆ๋‹ค. ๋„์‹œ์˜ ๊ฐ ์นธ์€ ๋นˆ ์นธ, ์น˜ํ‚จ์ง‘, ์ง‘ ์ค‘ ํ•˜๋‚˜์ด๋‹ค. ๋„์‹œ์˜ ์นธ์€ (r, c)์™€ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ๋‚˜ํƒ€๋‚ด๊ณ , rํ–‰ c์—ด ๋˜๋Š” ์œ„์—์„œ๋ถ€ํ„ฐ r๋ฒˆ์งธ ์นธ

www.acmicpc.net


๐Ÿ’ก ์ ‘๊ทผ ๋ฐฉ๋ฒ•

1. ๋ฌธ์ œ ์ดํ•ด & ์ ํ•ฉํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ฐพ๊ธฐ

์ตœ๋Œ€ ์น˜ํ‚จ์ง‘์˜ ๊ฐœ์ˆ˜(M) ๊ฐœ์—์„œ ๊ฐ€์žฅ ์ž‘์€ ์น˜ํ‚จ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ๋‹ค. ๋ชจ๋“  ์ตœ๋Œ€ ์น˜ํ‚จ์ง‘์˜ ๊ฐœ์ˆ˜๋ฅผ ํ™•์ธํ•˜๋ฉด์„œ ์ตœ์†Œ์˜ ๊ฐ’์„ ์ฐพ์œผ๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฑํŠธ๋ ˆํ‚น์„ ์‚ฌ์šฉ์„ ํ•˜๋Š” ๊ฒŒ ์ข‹์•„ ๋ณด์ธ๋‹ค. ๋น„์Šทํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ๋ธŒ๋ฃจํŠธ ํฌ์Šค๊ฐ€ ์žˆ๋Š”๋ฐ ์ฐจ์ด์ ์„ ํ™•์ธํ•ด ๋ณด์ž.

  • ๋ธŒ๋ฃจํŠธ ํฌ์Šค : ๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ํ™•์ธํ•จ / ๋…ธ๊ฐ€๋‹ค / ์ตœ์ ํ•ด๋ฅผ ๋ณด์žฅํ•œ๋‹ค
  • ๋ฐฑํŠธ๋ ˆํ‚น : ๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ํ™•์ธํ•˜์ง€๋งŒ ๋ฅผ ํ•ด์„œ ์›ํ•˜๋Š” ์กฐ๊ฑด์— ๋งŒ์กฑํ•˜์ง€ ๋ชปํ•˜๋ฉด ํƒ์ƒ‰์ค‘๋‹จ ํ›„ ์ด์ „ ๋‹จ๊ณ„๋กœ ๋Œ์•„๊ฐ / ๊ฐ€์ง€์น˜๊ธฐ

2. ๋ฌธ์ œ ํ’€์ด

๋ฐฑํŠธ๋ ˆํ‚น ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ BFS, DFS์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์–ด๋Š ์ •๋„ ์ •ํ•ด์ง„ ๊ทœ๊ฒฉ์ด ์žˆ๋‹ค. ์›ํ•˜๋Š” ์กฐ๊ฑด์„ ์„ค์ •ํ•˜๊ณ  ํƒˆ์ถœํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์—ฌ๊ธฐ์„œ ๋ฐฉ๋ฌธ์ฒดํฌ๋ฅผ ํ•˜๋Š” ์ด์œ ๋Š” ๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ํ™•์ธ์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋‹ค. ๋ฌด์Šจ ๋ง์ด๋ƒ๋ฉด ๋งŒ์•ฝ 4๊ฐœ์˜ ์น˜ํ‚จ์ง‘ ์ค‘์—์„œ 2๊ฐœ๋ฅผ ์„ ํƒํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์—, (1,2), (1,3), (1,4), (2,3), (2,4), (3,4)์™€ ๊ฐ™์ด ์ด 6๊ฐ€์ง€์˜ ์กฐํ•ฉ์„ ์ „๋ถ€ ๊ตฌํ•ด์„œ ์ตœ์†Œ ์น˜ํ‚จ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. 

private static void backtracking(int start, int depth) {
	// ํƒˆ์ถœ์กฐ๊ฑด ํ˜„์žฌ ๋ฌธ์ œ๋กœ ์ตœ๋Œ€์˜ ์น˜ํ‚จ์ง‘(M)๊ฐœ๋ฅผ ๊ณ„์‚ฐํ•˜๋ฉด ๋ฉ”์„œ๋“œ ์ข…๋ฃŒ
        if (depth == M) {
            calculate();
            return;
        }

        for (int i = start; i < chicken.size(); i++) {
            isVisited[i] = true;
            backtracking(i + 1, depth + 1);
            isVisited[i] = false;
        }
}

 

๋˜ํ•œ ๋ฐ‘์˜ calculate() ๋ฉ”์„œ๋“œ๋ฅผ ๋ณด๋ฉด ์—ฌ๊ธฐ์„œ๋„ ๋ฐฉ๋ฌธ์ฒดํฌ๋ฅผ ํ†ตํ•ด์„œ ์ตœ๋Œ€ ์น˜ํ‚จ์ง‘(M) ๊ฐœ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ตœ์†Œ ์น˜ํ‚จ๊ฐ’์„ ๊ณ„์‚ฐํ•œ๋‹ค. ์ด๊ฒŒ ๋ง์ด ์ข€ ์ด์ƒํ•œํ…Œ ์ถœ๋ ฅ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์„œ ํ™•์ธํ•ด ๋ณด๋ฉด ๋” ์‰ฝ๊ฒŒ ์ดํ•ด๊ฐ€ ๊ฐˆ ๊ฒƒ์ด๋‹ค.

private static void backtracking(int start, int depth) {
	if (depth == M) {
		calculate();
		// ์ถœ๋ ฅ ๋ถ€๋ถ„
		System.out.print("isVisited =");
		for(int i = 0; i < isVisited.length ; i++) {
			if(isVisited[i]) System.out.print(i + " ");
		}

		System.out.println();
		return;
	}

	for (int i = start; i < chicken.size(); i++) {
		isVisited[i] = true;
		backtracking(i + 1, depth + 1);
		isVisited[i] = false;
	}
}
// ์ž…๋ ฅ ๊ฐ’
5 2
0 2 0 1 0
1 0 1 0 0
0 0 0 0 0
2 0 0 1 1
2 2 0 1 2

// ๊ฒฐ๊ณผ
isVisited = 0 1 
isVisited = 0 2 
isVisited = 0 3 
isVisited = 0 4 
isVisited = 1 2 
isVisited = 1 3 
isVisited = 1 4 
isVisited = 2 3 
isVisited = 2 4 
isVisited = 3 4

 

์ด๋ ‡๊ฒŒ ๋ชจ๋“  ์กฐํ•ฉ์„ ์ฐพ์•„๋ณด๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ ์ž‘๋™๋ฐฉ์‹์„ ์š”์•ฝํ•˜์ž๋ฉด ์ด๋ ‡๊ฒŒ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ ๊ฐ™๋‹ค.

  1. backTracking() ๋ฉ”์„œ๋“œ ์‹คํ–‰
    • for๋ฌธ์„ ํ†ตํ•ด ๋ชจ๋“  ์น˜ํ‚จ์ง‘์„ ๋ฐฉ๋ฌธํ•œ๋‹ค / ์—ฌ๊ธฐ์„œ ํฌ์ธํŠธ๋Š” ์ตœ๋Œ€ ์น˜ํ‚จ์ง‘(M)์„ ๋งž์ถ”๊ธฐ ์œ„ํ•ด depth๋ฅผ + 1 ์”ฉ ํ•ด์ค€๋‹ค.
  2. ๊ทธ๋ ‡๊ฒŒ ์ตœ๋Œ€ ์น˜ํ‚จ์ง‘(M) ๊ฐœ๋ฅผ ๋งŒ์กฑํ•˜๋Š” depth๊ฐ€ ๋‚˜์™”๋‹ค ๊ทธ๋Ÿผ calculate() ๋ฉ”์„œ๋“œ ์‹คํ–‰
    • ํ˜„์žฌ ์ตœ๋Œ€ ์น˜ํ‚จ์ง‘์˜ ๊ฐœ์ˆ˜(M) ๊ฐœ์˜ ์น˜ํ‚จ์ง‘์ด ๋ฐฉ๋ฌธ์ฒดํฌ๊ฐ€ ๋˜์–ด์žˆ์œผ๋ฏ€๋กœ ๋ฐฉ๋ฌธ์ฒดํฌ๊ฐ€ ๋œ ์น˜ํ‚จ์ง‘๊ณผ ์ง‘์˜ ์น˜ํ‚จ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•œ๋‹ค.
    • ๊ทธ๋Ÿฐ ๋‹ค์Œ answer = Math.min(answer, sum)์„ ํ†ตํ•ด ์น˜ํ‚จ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐฑ์‹ ํ•œ๋‹ค.
  3. ๊ทธ๋Ÿผ ํƒ์ƒ‰ ์ข…๋ฃŒ ํ›„ ์ด์ „ ๋…ธ๋“œ๋กœ ๋Œ์•„๊ฐ€ 1๋ฒˆ for๋ฌธ์œผ๋กœ ๋‹ค์‹œ ๋Œ์•„๊ฐ€์„œ ์‹คํ–‰

4๊ฐœ์˜ ์น˜ํ‚จ์ง‘ ์ค‘์— ์ตœ๋Œ€ ์น˜ํ‚จ์ง‘์˜ ์ˆ˜๊ฐ€ 2๋ผ๋ฉด ์ฒ˜์Œ 0,1๋กœ ๊ณ„์‚ฐํ•˜๊ณ  ์ €๊ธฐ์„œ for ๋ฌธ์œผ๋กœ ๋Œ์•„๊ฐ€ 0,2๋กœ ๊ณ„์‚ฐํ•˜๊ณ  ๋˜ 0,3์œผ๋กœ ๊ณ„์‚ฐํ•˜๋Š” ์‹์œผ๋กœ ์ง„ํ–‰๋œ๋‹ค.


๐Ÿ— ํ’€์ด ์ฝ”๋“œ

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

public class Main {
    static int N, M, answer;
    static int[][] map;
    static boolean[] isVisited;
    static List<Point> house, chicken;

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

        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        answer = Integer.MAX_VALUE;

        map = new int[N][N];
        house = new ArrayList<>();
        chicken = new ArrayList<>();

        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < N; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
                if (map[i][j] == 1) house.add(new Point(i, j));
                if (map[i][j] == 2) chicken.add(new Point(i, j));
            }
        }

        isVisited = new boolean[chicken.size()];
        backtracking(0, 0);
        System.out.println(answer);
    }

    private static void backtracking(int start, int depth) {
        if (depth == M) {
            calculate();
            return;
        }

        for (int i = start; i < chicken.size(); i++) {
            isVisited[i] = true;
            backtracking(i + 1, depth + 1);
            isVisited[i] = false;
        }
    }

    private static void calculate() {
        int sum = 0;
        for (int i = 0; i < house.size(); i++) {
            int temp = Integer.MAX_VALUE;
            for (int j = 0; j < chicken.size(); j++) {
                if (isVisited[j]) {
                    int dist = Math.abs(house.get(i).x - chicken.get(j).x)
                            + Math.abs(house.get(i).y - chicken.get(j).y);
                    temp = Math.min(temp, dist);
                }
            }

            sum += temp;
        }

        answer = Math.min(answer, sum);
    }
}

class Point {
    int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

'Algorithm' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Java] 10971๋ฒˆ: ์™ธํŒ์› ์ˆœํšŒ 2  (1) 2024.04.10
[Java] 15664๋ฒˆ: N๊ณผ M(10)  (0) 2024.03.31
[Java] 2023๋ฒˆ: ์‹ ๊ธฐํ•œ ์†Œ์ˆ˜  (0) 2024.03.02
[Java] 19942๋ฒˆ: ๋‹ค์ด์–ดํŠธ  (0) 2024.02.01