알고리즘/백준
BOJ) 다리 만들기
Zin0_0
2021. 2. 14. 23:20
반응형
다리 만들기
2146번: 다리 만들기
여러 섬으로 이루어진 나라가 있다. 이 나라의 대통령은 섬을 잇는 다리를 만들겠다는 공약으로 인기몰이를 해 당선될 수 있었다. 하지만 막상 대통령에 취임하자, 다리를 놓는다는 것이 아깝다
www.acmicpc.net
여러 섬으로 이루어진 나라에서 가장 가까운 두 섬을 잇는 최단 거리 비용을 구하는 문제다.
최단 거리라고해서 해당 알고리즘들을 사용할 수 있을까 고민했는데, 떠오르지 않았다.
그래서 평소에 즐겨하던 grouping을 하면서, 모든 섬마다 전체 좌표를 List에 저장했다.
또한, 각 섬마다 위치를 식별할 수 있어야해서 위의 섬의 좌표를 저장하는 List를 List에 저장해주었다.
List<List<Island Position>> 으로 섬의 모든 좌표를 저장해주었다.
좌표를 모두 저장한 이후에는 각 섬들의 최소 연결비용을 구하며 답을 구해주었다.N이 100이하의 자연수로 주어지기 때문에, 모든 위치를 탐색했다.
시간 효율이 뛰어나지 않아서 더 좋은 방법이 있을까 고민해봤지만, 아직은 잘 모르겠다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class MakeBridge_2146 {
static final int DIRECTIONS = 4;
static final int[] dx = {1,-1,0,0}, dy = {0,0,1,-1};
static int n;
static boolean[][] map;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
map = new boolean[n][n];
final String ISLAND = "1";
for(int i=0; i<n; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for(int j=0; j<n; j++) {
if(st.nextToken().equals(ISLAND)) {
map[i][j] = true;
}
}
}
br.close();
solution();
}
private static void solution() {
boolean[][] visit = new boolean[n][n];
List<List<Pos>> islandList = new ArrayList<>();
setIslandList(visit,islandList);
int answer = Integer.MAX_VALUE;
int size = islandList.size();
for(int i=0; i<size; i++) {
for(int j=0; j<size; j++) {
if(i!=j) {
answer = Math.min(answer, getDist(islandList.get(i), islandList.get(j)));
}
}
}
System.out.println(answer);
}
private static int getDist(List<Pos> originList, List<Pos> targetList) {
int result = Integer.MAX_VALUE;
for(Pos origin : originList) {
for(Pos target : targetList) {
result = Math.min(result, Math.abs(origin.x - target.x) + Math.abs(origin.y - target.y) -1);
}
}
return result;
}
private static void setIslandList(boolean[][] visit, List<List<Pos>> islandList) {
for(int y=0; y<n; y++) {
for(int x=0; x<n; x++) {
if(!visit[y][x] && map[y][x]) {
Queue<Pos> queue = new LinkedList<>();
queue.offer(new Pos(x,y));
islandList.add(getIslandPosList(queue, visit));
}
}
}
}
private static List<Pos> getIslandPosList(Queue<Pos> queue, boolean[][] visit) {
List<Pos> islandPosList = new ArrayList<>();
Pos start = queue.peek();
visit[start.y][start.x] = true;
while(!queue.isEmpty()) {
Pos now = queue.poll();
islandPosList.add(now);
for(int i=0; i<DIRECTIONS; i++) {
int nx = now.x + dx[i], ny = now.y + dy[i];
if(isInRange(nx,ny) && !visit[ny][nx] && map[ny][nx]) {
queue.offer(new Pos(nx, ny));
visit[ny][nx] = true;
}
}
}
return islandPosList;
}
private static boolean isInRange(int x, int y) {
return x>=0 && x<n && y>=0 && y<n;
}
private static class Pos {
int x, y;
public Pos(int x, int y) {
this.x = x;
this.y = y;
}
}
}
반응형