본문 바로가기

알고리즘/SW 역량 테스트

[15686] 치킨 배달

반응형

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

 

15686번: 치킨 배달

크기가 N×N인 도시가 있다. 도시는 1×1크기의 칸으로 나누어져 있다. 도시의 각 칸은 빈 칸, 치킨집, 집 중 하나이다. 도시의 칸은 (r, c)와 같은 형태로 나타내고, r행 c열 또는 위에서부터 r번째 칸, 왼쪽에서부터 c번째 칸을 의미한다. r과 c는 1부터 시작한다. 이 도시에 사는 사람들은 치킨을 매우 좋아한다. 따라서, 사람들은 "치킨 거리"라는 말을 주로 사용한다. 치킨 거리는 집과 가장 가까운 치킨집 사이의 거리이다. 즉, 치킨 거리는

www.acmicpc.net


import java.util.Scanner;
import java.util.ArrayList;

class Main {
	
	static int N, M, L, len, answer;
	static int[][] arr;
	static ArrayList<House> house = new ArrayList<House>();
	static ArrayList<House> chicken = new ArrayList<House>();
	static ArrayList<House> select = new ArrayList<House>();
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		N = sc.nextInt();
		M = sc.nextInt();
		arr = new int[N][N];
		answer = 99999999;
		
		for(int i=0; i<N; i++) {
			for(int j=0; j<N; j++) {
				arr[i][j] = sc.nextInt();
				if(arr[i][j] == 1) house.add(new House(i, j)); 
				if(arr[i][j] == 2) chicken.add(new House(i, j));
				
			}
		}
		
		for(int i=0; i<chicken.size(); i++) select.add(new House(0, 0));
		
		for(int i=1; i<=M; i++) {
			L = i;
			combination(0, 0);			
		}
		
		System.out.println(answer);
	}
	
	public static void combination(int start, int depth) {
		if(depth == L) {	
			len = 0;
			calc();
			answer = Math.min(len, answer);
			return;
		}
		for(int i=start; i<chicken.size(); i++) {
			select.set(depth, chicken.get(i));
			combination(i+1, depth+1);
		}
	}
	
	public static void calc() {
		int min = 99999999;
		for(int i=0; i<house.size(); i++) {
			House h = house.get(i);
			min = 99999999;
			for(int j=0; j<L; j++) {
				House c = select.get(j);
				int length = Math.abs(h.x-c.x) + Math.abs(h.y-c.y);
				min = Math.min(min, length);
			}
			len += min;
		}
	}
}

class House {
	int x;
	int y;
	House(int x, int y){
		this.x=x;
		this.y=y;
	}
}

주어진 2차원 배열에서 0은 빈집, 1은 집, 2은 치킨집을 나타냅니다. 치킨집 중에 1개~M개를 선택하여 각각의 경우의 집까지의 치킨거리를 구해서 치킨거리의 최솟값을 구하는 문제입니다.  저는 select라는 ArrayList를 만들어서 뽑힌 치킨집을 넣고 각 경우에 치킨거리를 계산해서 최솟값을 출력하여 문제를 해결했습니다.

[ 문제 풀이 ]

1. ArrayList house 에 1로 표시된 집들을 모두 저장하고, ArrayList chicken에 2로 표시된 치킨집을 모두 저장합니다.

2. 그 다음에 모든 치킨집을 뽑았을 때 치킨거리를 계산해야하므로 뽑힌 치킨집을 넣을 ArrayList select 또한 chicken.size만큼 길이를 정해줍니다.

3. 그리고 치킨집을 1개부터 M개까지 뽑았을 경우의 각각 치킨거리를 계산하는 calc() 함수를 이용해서 최솟값을 출력하면 정답입니다.

반응형

'알고리즘 > SW 역량 테스트' 카테고리의 다른 글

[15683] 감시  (0) 2019.10.19
[16235] 나무 재테크  (0) 2019.10.18
[16234] 인구 이동  (0) 2019.10.16
[16236] 아기 상어  (0) 2019.10.16
[17140] 이차원 배열과 연산  (0) 2019.10.13