본문 바로가기
알고리즘 & 자료구조/백준

백준 1700

by 신재권 2023. 8. 21.

1700번: 멀티탭 스케줄링


문제

기숙사에서 살고 있는 준규는 한 개의 멀티탭을 이용하고 있다. 준규는 키보드, 헤어드라이기, 핸드폰 충전기, 디지털 카메라 충전기 등 여러 개의 전기용품을 사용하면서 어쩔 수 없이 각종 전기용품의 플러그를 뺐다 꽂았다 하는 불편함을 겪고 있다. 그래서 준규는 자신의 생활 패턴을 분석하여, 자기가 사용하고 있는 전기용품의 사용순서를 알아내었고, 이를 기반으로 플러그를 빼는 횟수를 최소화하는 방법을 고안하여 보다 쾌적한 생활환경을 만들려고 한다.

예를 들어 3 구(구멍이 세 개 달린) 멀티탭을 쓸 때, 전기용품의 사용 순서가 아래와 같이 주어진다면,

  1. 키보드
  2. 헤어드라이기
  3. 핸드폰 충전기
  4. 디지털 카메라 충전기
  5. 키보드
  6. 헤어드라이기

키보드, 헤어드라이기, 핸드폰 충전기의 플러그를 순서대로 멀티탭에 꽂은 다음 디지털 카메라 충전기 플러그를 꽂기 전에 핸드폰충전기 플러그를 빼는 것이 최적일 것이므로 플러그는 한 번만 빼면 된다.

입력

첫 줄에는 멀티탭 구멍의 개수 N (1 ≤ N ≤ 100)과 전기 용품의 총 사용횟수 K (1 ≤ K ≤ 100)가 정수로 주어진다. 두 번째 줄에는 전기용품의 이름이 K 이하의 자연수로 사용 순서대로 주어진다. 각 줄의 모든 정수 사이는 공백문자로 구분되어 있다.

출력

하나씩 플러그를 빼는 최소의 횟수를 출력하시오.

제한

  • 시간 제한 : 2초
  • 메모리 제한 : 128MB

문제 풀이 과정

만약 멀티탭 구가 꽉차있다면, 나중에 사용되는 것들을 제외한 것을 빼면 된다. 만약 모두 나중에 사용된다면, 최대한 늦게 사용하는 가전제품을 빼면 된다.

다음 프로세스로 진행한다.

  1. 사용하려는 가전제품이 이미 꽂혀있는 경우는 고려할 필요 없다.
  2. 만약 사용하려는 제품이 꽂혀있지 않은 경우
    1. 멀티탭 구멍이 남는다면, 비어있는 공간에 넣기
    2. 멀티탭 구멍이 남지 않는다면, 현재 사용 중인 가전제품과 나중에 사용될 가전제품을 비교한다. 즉, 현재 사용중이면서, 나중에 사용될 가전제품을 list에 넣어준다.
      1. 현재 사용 중인 가전제품 중, 나중에 사용되지 않을 가전제품이 있다면, 그것을 제거한다.
      2. 현재 사용 중인 가전제품 모두 나중에 사용될거라면, 가장 늦게 사용되는 가전제품을 제거한다.

정답 코드

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

class Main1700 {

	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		int N = Integer.parseInt(st.nextToken());
		int K = Integer.parseInt(st.nextToken());

		int[] A = new int[K];
		st = new StringTokenizer(br.readLine());
		for (int i = 0; i < K; i++) {
			A[i] = Integer.parseInt(st.nextToken());
		}

		boolean[] used = new boolean[101];
		int answer = 0;
		int put = 0; //현재 멀티탭에 꽂혀 있는 개수
		for (int i = 0; i < K; i++) {
			int tmp = A[i];
			if (!used[tmp]) { //2. 사용하려는 제품이 꽂혀있지 않은 경우
				if (put < N) { //2-1. 구멍이 남는다면, 비어있는 공간에 넣기
					used[tmp] = true;
					put++;
				} else { //2-2. 구멍이 없다면
					List<Integer> list = new ArrayList<>(); //사용될 가전제품을 담을 리스트
					for (int j = i; j < K; j++) {
						if (used[A[j]] && !list.contains(A[j])) { //콘센트들이 나중에 사용되는지 확인
							list.add(A[j]); //사용중인 가전제품 리스트에 넣는다.
						}
					}

					if (list.size() != N) { // 2-2-1. 콘센트 중 일부만 나중에 사용된다면
						for (int j = 0; j < used.length; j++) {
							if (used[j] && !list.contains(j)) {
								used[j] = false; //나중에 사용되지 않는 콘센트 제거
								break;
							}
						}
					} else { //2-2-2. 콘센트 중 모두 나중에 사용된다면
						int remove = list.get(list.size() - 1); //제일 늦게 사용되는 가전제품 제거
						used[remove] = false;
					}
					used[tmp] = true;
					answer++;

				}
			}
			//1. 이미 꽂혀있는 상태
		}

		System.out.println(answer);
	}
}

'알고리즘 & 자료구조 > 백준' 카테고리의 다른 글

백준 2309  (0) 2023.08.26
백준 2231  (0) 2023.08.25
백준 1202  (0) 2023.08.18
백준 3687  (0) 2023.08.15
백준 8980  (0) 2023.08.11