티스토리 뷰

Algorithm

[백준] S2 9367 관리 난항 (java)

코딩브론즈 2021. 7. 15. 01:12

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

 

9367번: 관리 난항

적절한 자동차는 첩보원의 필수품이다. BAPC로 알려진 한 렌트카 회사에서는 첩보원에게 어울릴 만한 자동차들을 방대하게 구비해두고 있으며, 사후처리까지 담당하고 있다. 첩보원으로부터 반

www.acmicpc.net

 

풀이

 

1) event = p 일 경우 (대여)

  1. 처음 보는 첩보원일 경우
  2. 처음 보는 첩보원도 아니고 차를 대여한 상태가 아닌 경우
  3. 처음 보는 첩보원은 아닌데 차를 대여한 상태인데 또 대여한다고 하는 경우

2) event = r 일 경우 (반납)

  1. 처음 보는 첩보원일 경우
  2. 처음 보는 첩보원은 아닌데 차를 대여도 안했는데 반납한다고 하는 경우
  3. 아닐 경우

3) event = a 일 경우 (사고)

  1. 처음 보는 첩보원일 경우
  2. 처음 보는 첩보원은 아닌데 차를 대여도 안했는데 사고났다고 하는 경우
  3. 아닐 경우

4) 차를 반납 안했을 경우

로 나누어서 풀자.

 

주의 사항

 

1) Math.ceil()을 쓸 때 인자 값으로 int 형을 쓸 때, 반드시 앞에 (double)을 붙여야 소수점 처리가 된다.

2) 알파벳 순서로 정렬해야한다.

3) 각 테스트 케이스 사이에 빈 공간이 없이 연속으로 출력해야한다.

 

package com.baekJoon;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

public class BJ_S2_9367_관리난항 {
	static BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
	static BufferedWriter output = new BufferedWriter(new OutputStreamWriter(System.out));
	static StringTokenizer tokens;
	static int T,N,M;
	
	
	public static void main(String[] args) throws NumberFormatException, IOException {
		input = new BufferedReader(new StringReader(src));
		T = Integer.parseInt(input.readLine());
		for(int t=0; t<T; t++) {
			Map<String, Car> cars = new HashMap<>();
			Map<String, Agent> agents = new HashMap<>();
			tokens = new StringTokenizer(input.readLine());
			N = Integer.parseInt(tokens.nextToken());
			M = Integer.parseInt(tokens.nextToken());
			for(int n=0; n<N; n++) {
				tokens = new StringTokenizer(input.readLine());
				String cName = tokens.nextToken();
				int cost = Integer.parseInt(tokens.nextToken());
				int rent = Integer.parseInt(tokens.nextToken());
				int perSec = Integer.parseInt(tokens.nextToken());
				cars.put(cName, new Car(cName, cost, rent, perSec));
			}
			for(int m=0; m<M; m++) {
				tokens = new StringTokenizer(input.readLine());
				int time = Integer.parseInt(tokens.nextToken());
				String aName = tokens.nextToken();
				char event = tokens.nextToken().charAt(0);
				String detail = tokens.nextToken();
			
				if(event == 'p') {
					if(agents.get(aName) == null) { // 처음 보는 새기가 빌리는 경우
						agents.put(aName, new Agent(aName, detail, cars.get(detail).rent, false)); // detail=차종
					}else { // 처음 보지 않는 새기가 빌리는 경우
						if(!agents.get(aName).isInconsistent && agents.get(aName).cName == null) { // 부적합이 아니면서 차를 반납한 첩보원, 새로 빌릴 수 있다.
							agents.replace(aName, new Agent(aName, detail, agents.get(aName).price + cars.get(detail).rent, false));
						}else { // 차를 반납하지 않은 상태에서 차를 또 빌리려는 염치없는 새기
							agents.get(aName).isInconsistent = true;
						}
					}
				}else if(event == 'r') {
					if(agents.get(aName) == null) { // 처음 보는데 반납한다고 하는새기
						agents.put(aName, new Agent(aName, null, 0, true)); // 바로 부적합 때려 버리기~
					}else if(agents.get(aName).cName == null){ // 처음은 아니지만 대여도 안했는데 반납한다는 새기
						agents.get(aName).isInconsistent = true;
					}else { // 드디어 정상인 새기
						agents.get(aName).price += cars.get(agents.get(aName).cName).perSec * Integer.parseInt(detail); // detail=주행거리
						agents.get(aName).cName = null; // 반납하면 null로 초기화
					}
				}else if(event == 'a') {
					if(agents.get(aName) == null) { // 처음 보는데 사고났다는 새기
						agents.put(aName, new Agent(aName, null, 0, true)); // 바로 부적합 때려 버리기~
					}else if(agents.get(aName).cName == null){ // 대여도 안했는데 사고났다고 하는 새기
						agents.get(aName).isInconsistent = true;
					}else{ // 정상적으로 사고난 새기
						agents.get(aName).price += Math.ceil((double)cars.get(agents.get(aName).cName).cost * Integer.parseInt(detail) / 100); // doubleㅅㅂ
					}
				}
			}
			List<Agent> result = new ArrayList<>(agents.values());
			Collections.sort(result);
			for(int i=0; i<result.size(); i++) {
				if(result.get(i).cName != null || result.get(i).isInconsistent) {
					output.append(result.get(i).aName + " INCONSISTENT\n");
				}else {
					output.append(result.get(i).aName + " " + result.get(i).price+"\n");
				}
			}
		}
		output.close();
	}
	static class Car {
		String cName;
		int cost;
		int rent;
		int perSec;
		
		public Car(String cName, int cost, int rent, int perSec) {
			super();
			this.cName = cName;
			this.cost = cost;
			this.rent = rent;
			this.perSec = perSec;
		}
	}
	
	static class Agent implements Comparable<Agent>{
		String aName;
		String cName;
		int price;
		boolean isInconsistent;
		public Agent(String aName, String cName, int price, boolean isInconsistent) {
			super();
			this.aName = aName;
			this.cName = cName;
			this.price = price;
			this.isInconsistent = isInconsistent;
		}
		@Override
		public String toString() {
			return "Agent [aName=" + aName + ", cName=" + cName + ", price=" + price + ", isInconsistent="
					+ isInconsistent + "]";
		}
		@Override
		public int compareTo(Agent o) {
			return this.aName.compareTo(o.aName);
		}
	}
	static String src =
			"1\r\n" + 
			"2 8\r\n" + 
			"bmw 5000 150 10\r\n" + 
			"jaguar 7000 200 25\r\n" + 
			"10 mallory p bmw\r\n" + 
			"15 jb p jaguar\r\n" + 
			"20 jb r 500\r\n" + 
			"35 badluckbrian a 100\r\n" + 
			"50 mallory a 10\r\n" + 
			"55 silva p jaguar\r\n" + 
			"60 mallory r 100\r\n" + 
			"110 silva a 30";
}

 

후기

 

이 문제는 난이도로 치면 그냥 머리 아픈 시뮬레이션 문제이지만 3가지를 제대로 알게된 귀한 문제다.

  1. class를 "문자열"을 기준으로 정렬하기 위해 return this.aName.compareTo(o.aName); 과 같이 쓴다는 점.
  2. Map을 List로 바꾸기 위해 new ArrayList<>(map.values()) 라는 api를 쓸 수 있다는 점.
  3. Math.ceil() 을 쓸 때 파라미터가 전부 int형 일 경우 앞에 (double)을 붙여줘야 한다는 점.

을 알게 되었다. 너무 짜증났지만 좋은 경험을 한 문제이다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함