본문 바로가기

코딩테스트 연습/SW Expert Academy

[ SWEA / 2477번 ] [모의 SW 역량테스트] 차량 정비소 - solved by Java

swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV6c6bgaIuoDFAXy

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

 

[ 풀이 ] 

여기에서 중요한 부분은 어떤 순서인지 였다. 

둘 다 같은 순서인줄 알았는데.. 아니었다.. ㅠㅜㅠㅜ  역시 문제를 잘 읽어야 하는데ㅠㅠ 다음에 진짜 문제 꼼꼼히 읽고 쓰면서 풀꺼다ㅠㅠㅠ

중요한 부분은  처음 접수 창구의 우선순위와 / 정비 창구의 우선순위가 다르다는 점이다. 

1. 접수 창구의 우선순위 

1-1. 여러 고객이 기다리고 있는 경우, 고객 번호가 낮은 순서대로 우선 접수한다.

( 그런데 고객 번호가 온 순서니까 그대로 순서대로 처리하면 된다. )

1-2. 빈 창구가 여러 곳이 녁ㅇ우 접수 창구 번호가 작은 곳으로 간다. 

현재 대기 하는 사람이 들어온 순서보다 작은 대기 시간을 가진 곳이면 0부터 돌면서 return 해주면 된다. 

2.  정비 창구의 우선순위 

2-1. 먼저 기다리는 고객이 우선한다. (시간 순으로 정렬을 한다) 코드에서는 tk[i][0]으로 정렬해 주었다. 

2-2. 두 명 이상의 고객들이 접수 창구에서 동시에 접수를 완료하고 정비 창구로 이동한 경우, 이용했던 접수 창구 번호가 작은 고객이 우선한다. : 

이걸 위해서 접수 창구 번호를 tk[i][2]에 저장해 두었다.  두번쨰 정렬 순서는 tk[i][2]가 된다. 

2-3. 빈 창구가 여러 곳이 ㄴ경우 정비 창구번호가 작은 곳으로 간다. ( 이건 1-2.번과 동일하다. 0->M으로 가면서 처리 가 된다. ) 

[ 풀이 코드 ]

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class 차량정비소 {
	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader br= new BufferedReader(new InputStreamReader(System.in));
		int T = Integer.parseInt(br.readLine());
		StringBuilder sb = new StringBuilder();
		for(int tc = 1; tc<=T;tc++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			int N = Integer.parseInt(st.nextToken());
			int M = Integer.parseInt(st.nextToken());
			int K = Integer.parseInt(st.nextToken());
			int A = Integer.parseInt(st.nextToken())-1;
			int B = Integer.parseInt(st.nextToken())-1;
			int [] ai = new int[N];
			st = new StringTokenizer(br.readLine());
			for(int i =0; i< N; i++) {
				ai[i] = Integer.parseInt(st.nextToken());
			}
			int[]bi = new int[M];
			st = new StringTokenizer(br.readLine());
			for(int i = 0; i< M ; i++) {
				bi[i] = Integer.parseInt(st.nextToken());
			}
			int [][]tk = new int[K][3];// 도착시간, 고객번호,이용 창구
			st = new StringTokenizer(br.readLine());
			for(int i =0; i< K ;i++) {
				tk[i][0] = Integer.parseInt(st.nextToken());
				tk[i][1] = i+1;
			}// 입력 완료 
			int ans = 0; 
			int [] time = new int[N];// 대기시간 
			for(int i =0; i< K ;i++) { // 고객 입장 시작  , 이거 들어오는 거 고객 번호순이니 막 하면 됨
				int mi = 0; 
				for(int n = 0; n<N; n++) {
					if(time[n]<=tk[i][0]) {
						mi = n; 
						break;
					}else if(time[n]<time[mi]) {
						mi = n;
					}
				}
				tk[i][2] = mi;
				time[mi] = time[mi]<tk[i][0]?tk[i][0]+ai[mi]:time[mi]+ai[mi];
				tk[i][0] = time[mi];
			}// 접수 끝 
			Arrays.sort(tk, (a,b)->(a[0]!=b[0]?a[0]-b[0]:a[2]-b[2]));
			time = new int[M];
			for(int i = 0; i<K; i++) {
				int mi = 0; 
				for(int n= 0; n<M; n++) {
					if(time[n]<=tk[i][0]) {
						mi = n;
						break;
					}else if(time[n]<time[mi]) {
						mi = n;
					}
				}
				time[mi] = time[mi]<tk[i][0]?tk[i][0]+bi[mi]:time[mi]+bi[mi];
				if(mi == B && tk[i][2]==A) {
					ans+=tk[i][1];
				}
			}
			sb.append('#').append(tc).append(' ').append(ans==0?-1:ans).append('\n');
			
		}
		System.out.println(sb);
	}
}

이 부분이 위에서 썻던 1. 조건이다. mi으로 우선순위를 검사하게 된다. 

그리고 어느 창구로 갈 지정해지면 time[mi]의 값이 변하고, tk에는 끝나는 시간, 들어간 창구번호가 저장된다. 

그리고 여기가 또 중요한 부분인데, 2조건이 2-1과 2-2를 위해 정렬을 해주는 단계이다. 

정렬 하고 나머지 조건을 진행하면 된다. 

여기서 이제 A,B를 통해 지값을 분실한 고객과 같은 접수 창구인지 확인하게 된다. 

(A,B는 받을 떄 1을 뺴주어 배열과 바로 비교 가능하도록 했다. )