[백준] 1700 멀티탭 스케줄링 (JAVA)

2025. 10. 22. 14:53·코딩 테스트

문제 링크:

1700번: 멀티탭 스케줄링

 

 

난이도: 골드 1

 

 

문제:

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

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

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

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

 

 

입력:

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

 

 

출력:

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

 

 

문제 이해:

이 문제는 OS Optimal 스키줄링 기법과 똑같은 문제이다.

첫 줄에 콘센트 개수와 전기용품 사용 횟수가 주어지며

두번째 줄에 전기용품 사용 순서가 주어진다.

 

이때 플러그 교체를 최소한으로 하는 개수를 찾는 문제이다.

 

말로 설명하면 햇갈릴 수 있다. 바로 예제 입력 1로 예를 들어보자

위를 확인하면 5번에서 한번, 마지막 7번에서 한번 교체하여 총 2번 교체하는 것이다.

 

 

구현 방향:

실제로 Os Optimal 스케줄링 기법에서 그리디 방식이 사용된다. 따라서 이또한 그리디 방식으로 해결할 수 있다.

즉 우리는 어떤 전기용품이 일찍나오고, 나중에 나올지 알기 때문에

현재 연결되어있는 플러그중 가장 나중에 나오거나 나오지 않는 플로그로 교체하는 방식을 사용하면 된다.

 

순서는 다음과 같다.

1. 플러그가 가득찰때 까지 연결

2. 연결되어있는 플러그중 앞으로 나오지 않거나 가장 늦게나오는 플러그 제거

3. 새로운 플러그 연결

4. 이를 끝날때 까지 반복

 

이를 코드로 그대로 구현하면 다음과 같다.

 

 

정답 코드:

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

public class Main {
    static int N,K;
    static int[] arr; // 전기용품 배열
    static boolean []flag;
    static int[] dist;
    static int max=-1;
    static int result=0;
    static Set<Integer> curPlug=new HashSet<>();

    //OS Optimal page 기법 스케줄링
    public static void scheduling(){
        //초기에 멀티탭이 찰때까지 연결
        for(int i=0; i<K; i++){
            if(curPlug.size()==N)break;
            flag[arr[i]]=true;
            curPlug.add(arr[i]);
        }


        //가득 찰때 이후부터 스케줄링 시작
        for(int i=N; i<K; i++){
            Arrays.fill(dist,101);
            //이미 연결되어있는 플러그인 경우
            if(flag[arr[i]]) continue;

            //플러그를 교체해야 하는 경우
            //가장 나중에 연결할 플러그 거리 계산 안꼽혀있으면 101
            for(int j=K-1; j>=i; j--){
                if(curPlug.contains(arr[j])){
                    dist[arr[j]]=j;
                }
            }

            int max=-1;
            int maxIndex=-1;

            //꼽혀 있는 플러그중 가장 먼것 찾기
            for(Integer plug: curPlug){
                if(max<dist[plug]) {
                    max=dist[plug];
                    maxIndex=plug;
                }
            }

            //가장 먼것을 제거하고 새로운 플러그 연결
            if(maxIndex!=-1) curPlug.remove(maxIndex);
            flag[maxIndex]=false;
            curPlug.add(arr[i]);
            flag[arr[i]]=true;
            result++;

        }


    }

    public static void main(String[] args) throws IOException {
        //초기 세팅
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st=new StringTokenizer(br.readLine());
        N=Integer.parseInt(st.nextToken());
        K=Integer.parseInt(st.nextToken());

        arr=new int[K];

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

        }
        flag=new boolean[max+1];
        dist=new int[max+1];
        //초기 세팅 끝

        //스케줄링 시작
        scheduling();

        //결과 출력
        System.out.println(result);

    }
}

 

 

마무리하며:

이번 문제는 골드 1 난이도라 처음에는 겁을 먹었지만, 다행히 학부 시절 운영체제(OS) 시간에 배운 스케줄링 기법과 유사한 원리를 사용해 해결할 수 있었다.
즉, OPT(Optimal) 페이지 교체 알고리즘과 동일한 방식이라는 점을 깨닫고 나니 접근이 훨씬 쉬워졌다.

 

 

감사합니다.

'코딩 테스트' 카테고리의 다른 글

[백준] 14889 스타트와 링크 (JAVA)  (0) 2025.10.24
[백준] 17144 미세먼지 안녕! (JAVA)  (0) 2025.10.23
[백준] 3273 두 수의 합 (JAVA)  (0) 2025.10.21
[백준] 13144 List of Unique Numbers (JAVA)  (0) 2025.10.20
[백준] 1644 소수의 연속합 (JAVA)  (0) 2025.10.19
'코딩 테스트' 카테고리의 다른 글
  • [백준] 14889 스타트와 링크 (JAVA)
  • [백준] 17144 미세먼지 안녕! (JAVA)
  • [백준] 3273 두 수의 합 (JAVA)
  • [백준] 13144 List of Unique Numbers (JAVA)
0kingki_
0kingki_
자바 + 스프링 웹 개발
  • 0kingki_
    0kingki_
    0kingki_
  • 전체
    오늘
    어제
    • 분류 전체보기 (134)
      • 코딩 테스트 (54)
      • 자바 (21)
      • 스프링 (27)
      • 타임리프 (16)
      • 스프링 데이터 JPA (8)
      • 최적화 (2)
      • QueryDSL (4)
      • AWS (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    코딩테스트
    QueryDSL
    스프링 컨테이너
    스프링 데이터 JPA
    다형성
    자바
    쿼리
    dfs
    불변객체
    백준
    최적화
    컬렉션
    LocalDateTime
    SOLID
    스프링
    예외처리
    spring
    BFS
    thymeleaf
    fetch join
    타임리프
    예외 처리
    SpringDataJpa
    mvc
    객체지향
    Java
    쿼리dsl
    JPA
    재귀
    코딩 테스트
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
0kingki_
[백준] 1700 멀티탭 스케줄링 (JAVA)
상단으로

티스토리툴바