개발 공부/코딩테스트

99클럽 코테 스터디 8일차 TIL - 해시

죽밥죽밥화이팅 2024. 11. 5. 03:00

문제

백준 25593 [근무 지옥에 빠진 푸앙이(Small)]

문제 링크:  https://www.acmicpc.net/problem/25593

 

접근 방법

  • HashMap을 사용해 각 근무자의 이름을 키로, 누적 근무 시간을 값으로 저장
  • for 문을 돌며 각 직원의 작업 시간을 누적 -> 해당 부분에서 어려움을 느껴 결국 구글링 ㅜㅜ
  • Collections.max(map.values())와를 Collections.min(map.values())사용하여 최댓값과 최솟값 반환
  • 최댓값과 최솟값의 차이가 12 이하라면 "예", 아니면 "아니요"를 출력
    • map이 비어있다면(모든 직원이 근무하지 않는 경우), "예"를 종료


코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;


public class Main {

    public static void main(String[]args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        int N = Integer.parseInt(st.nextToken());
        Map<String, Integer> map = new HashMap<>();

        int[] time = {4, 6, 4, 10}; // 근무 시간

        // 주차별로 값을 받아서 저장
        for( int i = 0; i < N * 4; i++ ){
            int currentTime = time[i % 4];

            st = new StringTokenizer(br.readLine());
            for( int j = 0; j < 7; j++){

                String name = st.nextToken();
                if(!name.equals("-")){
                    map.put(name, map.getOrDefault(name, 0) + currentTime);
                }
            }
        }

        // 모든 값이 없을 경우 처리하는 구문
        if(map.isEmpty()) {
            System.out.println("Yes");
            return;
        }

        // 최소 / 최대값 구하는 문
        Integer maxValue = Collections.max(map.values());
        int minValue = Collections.min(map.values());


        // 값으로 출력값 정하는 구문
        if(maxValue - minValue <= 12) {
            System.out.println("Yes");
        } else {
            System.out.println("No");
        }

    }
}
더보기

 

for문 설명

  1. for( int i = 0; i < N * 4; i++ ): 이 부분은 전체 주차 수( N)와 각 주의 4개 작업 시간 대를 고려하여 반복 실행합니다. 이에 따라 N * 4공동작업을 수행합니다.
  2. int currentTime = time[i % 4];: 이 부분은 time배열에서 현재 작업 시간대의 작업 시간을 가져오는 역할입니다. i % 4를 사용하여 0, 1, 2, 3(0, 1, 2, 3번째 일하는 시간대)을 반복적으로 순회합니다.
  3. st = new StringTokenizer(br.readLine());: 이 부분은 현재 라인의 입력을 StringTokenizer분리합니다.
  4. for( int j = 0; j < 7; j++){: 이 부분은 한 줄에 있는 7개의 이름(또는 "-")을 순회합니다.
  5. String name = st.nextToken();: 이 부분은 StringTokenizer다음의 의미(이름 또는 "-")를 가져오는 주체입니다.
  6. if(!name.equals("-")){: 이 부분은 현재 이름이 "-"가 아닌 경우에만 처리됩니다. "-"는 작동하지 않고 나타납니다.
  7. map.put(name, map.getOrDefault(name, 0) + currentTime);: 이 부분은 현재 이름의 총 일하는 시간을 map기대합니다. map.getOrDefault(name, 0)해당 지역의 원래 값을 가져오고, 소유에 currentTime더하여 새로운 값을 저장합니다.

이 과정을 통해 각 직원의 총 근무 시간이 map에 도움이 되도록 합니다. 이후 최소/최대 작업 시간을 변형하여 압축하여 결과를 출력하는 부분이 이어집니다.

 

 

  • 참고할 다른 풀이 방법
더보기
  • LinkedHashMap<>()
import java.io.*;
import java.util.*;

public class Main {
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		StringBuilder sb = new StringBuilder();
		int n = Integer.parseInt(br.readLine()); // 주의 개수
		
		Map<String, Integer> map = new LinkedHashMap<>();
		List<Integer> list;
		StringTokenizer st;
		String name;
		
		// 주의 개수만큼 반복
		while (n-- > 0) {
			
			// 한 주에 4개의 시간 타임
			for (int i = 1; i <= 4; i++) {
				st = new StringTokenizer(br.readLine());
				
				// 한 주에 7일
				for (int j = 0; j < 7; j++) {
					name = st.nextToken();
					
					// 근무자가 없다면
					if (name.equals("-")) {
						continue;
					}
					
					// 근무자가 있지만 처음 근무한다면 생성
					if (!map.containsKey(name)) {
						map.put(name, 0);
					}
					
					// 근무 시간 추가
					map.put(name, map.get(name) + time(i));
				}
			}
		}
		
		// 근무자가 1명도 없었다면
		if (map.size() == 0) {
			sb.append("Yes");
		} else {
			list = new ArrayList<>(map.values());
			Collections.sort(list);
			
			// 제일 큰값에서 제일 작은 값을 뺏을 때 12시간을 초과한다면
			if (list.get(list.size() - 1) - list.get(0) > 12) {
				sb.append("No");
			} else {
				sb.append("Yes");
			}
		}
		
		bw.write(sb.toString());
		bw.flush();
		bw.close();
		br.close();
	}
	
	// 시간 타임마다 근무 시간이 다르기 때문에 근무 시간을 찾아주는 함수.
	private static int time(int t) {
		if (t == 1 || t == 3) {
			return 4;
		} else if (t == 2) {
			return 6;
		} else {
			return 10;
		}
	}
}

출처: https://steadycoding-turtleman.tistory.com/entry/BEAKJOON-백준-JAVA-25593번-근무-지옥에-빠진-푸앙이-Small 

 

  • StringTokenizer
import java.io.*;
import java.util.*;

class Main {
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		Map<String, Integer> map = new HashMap<>();
		List<Integer> list;
		StringTokenizer st;
		String name;
        int workTime;
        
        int n = Integer.parseInt(br.readLine()); 
		
		// 주의 개수만큼 반복
		while (n-- > 0) {
			
			// 한 주에 4개의 시간 타임
			for (int i = 1; i <= 4; i++) {
				st = new StringTokenizer(br.readLine());
    
                if(i == 1 || i == 3) workTime = 4;
                else if(i == 2) workTime = 6;
                else workTime = 10;
				
				// 한 주에 7일
				for (int j = 0; j < 7; j++) {
					name = st.nextToken();
					
					// 근무자가 없다면
					if (name.equals("-")) {
						continue;
					}
					
					// 근무 시간 추가
					map.put(name, map.getOrDefault(name, 0) + workTime);
				}
			}
		}
		
		// 근무자가 1명도 없었다면
		if (map.size() == 0) {
		    System.out.println("Yes");
		} else {
			list = new ArrayList<>(map.values());
			Collections.sort(list);
			
			// 제일 큰값에서 제일 작은 값을 뺏을 때 12시간을 초과한다면
			if (list.get(list.size() - 1) - list.get(0) > 12) System.out.println("No");
            else System.out.println("Yes");
		}

		br.close();
	}
}

 

  • Math.max&min
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

public class Main {

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		Map<String, Integer> m = new HashMap<>();
		int n = Integer.parseInt(br.readLine()) * 4;
		int[] arr = {4, 6, 4, 10};
		for (int i = 0; i < n; i++) {
			int time = i % 4;
			String[] s = br.readLine().split(" ");
			for (int j = 0; j < s.length; j++) {
				if (s[j].equals("-")) {
					continue;
				}
				m.put(s[j], m.getOrDefault(s[j], 0) + arr[time]);

			}
		}
		int max = -1;
		int min = 1000000;
		for (Map.Entry<String, Integer> entry : m.entrySet()) {
			String s = entry.getKey();
			Integer integer = entry.getValue();
			max = Math.max(integer, max);
			min = Math.min(integer, min);
		}
		if (max == -1) {
			System.out.println("Yes");
			return;
		}
		if (max - min > 12) {
			System.out.println("No");
			return;
		}
		System.out.println("Yes");

	}

 

  •  
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine()); //주의 개수 N
        Map<String, Integer> workerMap = new HashMap<String, Integer>();
        /**
         * 4교대 근무
         * 08:00-12:00 --> 첫째줄
         * 12:00-18:00 --> 둘째줄
         * 18:00-22:00 --> 셋째줄
         * 22:00-08:00 --> 넷째줄**/

        //둘째 주부터 근무표
        for (int i = 1; i <= N * 4; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            int time = 0;
            while(st.hasMoreTokens()){
                String name = st.nextToken();
                if(!name.equals("-")){
                        int currentHours = workerMap.getOrDefault(name, 0);
                        if (i % 4 == 1 || i % 4 == 3) {
                            workerMap.put(name, currentHours+4);
                        }else if(i%4==2){
                            workerMap.put(name, currentHours+6);
                        }else if(i%4==0){
                            workerMap.put(name, currentHours+10);                    }
                    }
            }
        }
        int max = 0;
        int min = 100000;
        for(Map.Entry<String, Integer> entry : workerMap.entrySet()){
            int value = entry.getValue();
            if(max<value){
                max = value;
            }
            if(min>value){
                min = value;
            }
        }
        if(max-min <=12){
            System.out.println("Yes");
        }else{
            System.out.println("No");
        }
    }
}