티스토리 뷰

728x90

문제

https://programmers.co.kr/learn/courses/30/lessons/42583?language=java 

 

코딩테스트 연습 - 다리를 지나는 트럭

트럭 여러 대가 강을 가로지르는 일차선 다리를 정해진 순으로 건너려 합니다. 모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 알아내야 합니다. 다리에는 트럭이 최대 bridge_length대 올라갈

programmers.co.kr

 

풀이 및 소스코드

 

하 이 문제는 풀 때마다 어렵고 풀기가 싫다.

고려해줘야할 조건이 많아서 그런 것 같다.

머리가 안돌아가.. ~~

 

파이썬으로 할 때는 answer을 0부터 시작해도 맞는 답이 나왔는데, 자바로 푸니 1씩 적게 나와서 애초에 answer을 1로 초기화 시켜놓고 풀었더니 pass 할 수 있었다.

 

cross : 다리를 지나고 있는 트럭

pass : 다리를 건넌 트럭

time : 다리를 지나고 있는 트럭들에 대한 경과 시간이 담긴 ArrayList

time을 사용한 이유는 시간이 흐를 때 마다 +1씩 해줘야했기 때문이다.

(파이썬은 큐의 요소도 수정할 수 있는데 자바는 안되나보다.)

 

먼저 cross와 sum에 첫번째 트럭의 무게를 담고, time에는 0을 넣는다.

(마찬가지로 파이썬에는 큐의 합을 계산하는 sum 함수가 있는데 자바는 없... 읍ㄷ읍.. 큐에 들어오면 일일히 더해주고 pop하면 빼줘야한다.)

 

[time의 기능]

다리가 버틸 수 있는 무게가 총 10이며, 길이가 2인 다리에 진입한다고 하자.

무게 5인 트럭 진입

time : [0]

무게 3인 트럭 진입과 동시에 1초의 시간이 흐름.

time : [1, 0]

무게 2인 트럭 진입 하려고 했으나, 길이 2인 다리 꽉 참. 1초의 시간만 흐른다.

time : [2, 1]

2초가 지나 맨 처음 진입한 트럭 다리 통과 완료. time.pop();

time : [1]

 

지나간 트럭이 n보다 같아지기 전까지 while 문을 돌린다. 

 

먼저, while문이 시작될 때 현재 다리를 지나는 트럭에 대한 시간을 +1 해준다. 그리고 answer 에도 +1을 해준다.

시간이 1 흘렀음을 의미한다.

 

그렇게 증가된 time 의 첫번째 요소( 즉, 제일 먼저 들어온 트럭에 대한 경과시간 )가 다리의 길이(bridge_length)와 같아지면 다리에서 내려오게 되므로, cross에서 pop해주고 pass에 add 해준다. 또한 다리에 있는 트럭이 하나 빠졌으므로 다리 위에 있는 트럭들 무게의 총합을 담고있는 sum에서 그 값만큼 빼준다.

 

그리고 다음 트럭을 올릴 수 있는지 여부도 따져봐야 한다.

만약 제일 최근에 다리에 올린 트럭의 idx 값이 nowidx 라면 nowidx+1 번째가 존재하는 지 보고,

존재한다면 sum에 그 트럭의 무게를 더해도 다리가 버틸 수 있는 weigth 보다 같거나 작은지 확인한다.

만약 작거나 같다면 cross에 다리를 추가하고, time에 0이라는 시간을 추가하고, sum에 그 무게를 추가하고, nowidx = nowidx+1을 해준다.

이렇게 반복하다보면 트럭들이 다리를 전부 지나게 되고, while문이 끝나게 된다.

 

import java.util.*;

class Solution {
	public static int solution(int bridge_length, int weight, int[] truck_weights) {
		int answer =1;
		Queue<Integer> cross = new LinkedList<Integer>();
		Queue<Integer> pass = new LinkedList<Integer>();
		ArrayList<Integer> time = new ArrayList<Integer>();
		int n= truck_weights.length;
		cross.add(truck_weights[0]);
		time.add(0);
		int nowidx = 0;
		int sum = truck_weights[0];
		while(pass.size()<n) {
			int time_n = time.size();
			for(int i=0;i<time_n;i++) time.set(i, time.get(i)+1);
			answer ++;
			if(time.get(0)==bridge_length) {
				int byetruck = cross.remove();
				pass.add(byetruck);
				time.remove(0);
				sum -= byetruck;
			}
			if(nowidx+1 <n ) {//고려할 트럭이 더 있으면!
				if(sum+truck_weights[nowidx+1]<=weight) {
					cross.add(truck_weights[nowidx+1]);
					time.add(0);
					sum += truck_weights[nowidx+1];
					nowidx += 1;
				}
			}
		}
		return answer;
	}
	public static void main(String[] args) {
		int b = 100;
		int w = 100;
		int[] t = {10};
		System.out.println(solution(b, w, t));

	}

}
반응형