반응형

백준 29812 아니 이게 왜 안돼

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

 

29812번: 아니 이게 왜 안 돼

과제를 하다가 잔뜩 화가 난 김한양은 분노 조절을 위해 메모장을 열어서 키보드를 내려치기 시작했다. 메모장에는 알파벳으로만 이루어진 알 수 없는 문자열이 생겼지만, 이상하게도 H, Y, U 세

www.acmicpc.net

접근 방식

문자열 자체를 입력받은 후 문자열의 위치를 저장하는 Queue에 담았다.

queue를 통해 각 요소를 소비하며 문자가 2개 이상일때는 그리디의 조건인 드래그 없는 문자만 삭제하는게 저렴한지, 드래그한 후에 삭제하는 것이 저렴한지 구분하며 각 에너지를 더해주고, 이후 HYU의 개수를 기준으로 H,Y,U중 수가 적은 것을 기준으로 HYU묶음 개수를 출력

묶음이 있어서 이번에 배워본 groupingBy를 활용했는데, 아마 더 상세하게 바꿀 수 있을 것 같은데 아직 많이 헷갈려서 제대로 활용은 못해봤다 아직은 사용하면서 익숙해지는데 더 힘을 써봐야겠다.


구현 방법

  • 그리디 조건을 위한 문자 길이체크 count
  • HYU가 아닌 인덱스 위치를 담아둔 Queue
  • 각 스트림 매핑 후 H,Y,U를 담기위한 Map

Queue의 값을 계속 체크하면서 인덱스 차이가 1 이상이면 범위가 벗어난 것
벗어난 범위 기준으로 {카운트 * d(각 문자를 개별딜리트)} vs {d + m} 비교 후 저렴한 것 선택 후 energe에 합치기

→ HYU매핑은 입력받은 문자열 그대로 다시사용해서 굳이 스트림 .chars로 변환 후 각 요소의 H,Y,U를 각각 맵에 담는 형식으로 구현

기존의 문자열에 .append로 HYU를 굳이 추가했는데 이유는 stream으로 매핑할때
아래의 반례는 Map 안에 H관련한 값만 생기기 때문이였다.
1
H
1 3

풀이

package Baekjoon.silver;

import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

public class p29812 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int energy = 0;
        int n = Integer.parseInt(br.readLine());

        StringBuilder sb = new StringBuilder();
        sb.append(br.readLine()).append("HYU");
        StringTokenizer st = new StringTokenizer(br.readLine());
        int d = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());
        ArrayList<Map<Integer, int[]>> removeRange = new ArrayList<>();

        Queue<Integer> noHYUList = new LinkedList<>();
        for (int i = 0; i < n; i++) {
            if (!isHYU(sb.charAt(i))){
                noHYUList.add(i);
            }
        }

        boolean flag;

        while(!noHYUList.isEmpty()){
            flag = false;
            final int firstIndex = noHYUList.poll();
            int prevIndex = firstIndex;
            int count = 1;

            while(!noHYUList.isEmpty()){
                int isContinuousIndex = noHYUList.peek();
                if(isContinuousIndex-prevIndex == 1){
                    prevIndex = noHYUList.poll();
                    flag = true;
                    count++;
                }else {
                    break;
                }
            }
            if(!flag || count * d < m+d){
                energy+= d*count;
            }else{
                energy += d + m;
            }
        }

        Map<Integer, List<Integer>> result = sb.toString().chars()
                .boxed()
                .filter(c -> isHYU(c))
                .collect(Collectors.groupingBy(c -> c));

        int min = Integer.MAX_VALUE;
        for(int num : result.keySet()){
            min = Integer.min(result.get(num).size(), min);
        }

        sb = new StringBuilder();
        if(energy == 0){
            sb.append("Nalmeok");
        }else{
            sb.append(energy);
        }
        sb.append(System.lineSeparator());
        if(min == 1 || Integer.MAX_VALUE == min){
            sb.append("I love HanYang University");
        }else{
            sb.append(min-1);
        }
        System.out.println(sb);

    }

    static boolean isHYU(int a) {
        switch (a) {
            case 'H', 'Y', 'U':
                return true;
            default:
                return false;
        }
    }
}
package Baekjoon.silver;

import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

public class p29812 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int energy = 0;
        int n = Integer.parseInt(br.readLine());

        StringBuilder sb = new StringBuilder();
        sb.append(br.readLine()).append("HYU");
        StringTokenizer st = new StringTokenizer(br.readLine());
        int d = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());

        Queue<Integer> noHYUList = new LinkedList<>();
        for (int i = 0; i < n; i++) {
            if (!isHYU(sb.charAt(i))) {
                noHYUList.add(i);
            }
        }

        boolean flag;

        while (!noHYUList.isEmpty()) {
            flag = false;
            final int firstIndex = noHYUList.poll();
            int prevIndex = firstIndex;
            int count = 1;

            while (!noHYUList.isEmpty()) {
                int isContinuousIndex = noHYUList.peek();
                if (isContinuousIndex - prevIndex == 1) {
                    prevIndex = noHYUList.poll();
                    flag = true;
                    count++;
                } else {
                    break;
                }
            }
            if (!flag || count * d < m + d) {
                energy += d * count;
            } else {
                energy += d + m;
            }
        }

        Map<HYU, Long> result = sb.toString().chars()
                .filter(c -> isHYU(c))
                .boxed()
                .collect(Collectors.groupingBy((Integer c) -> HYU.valueOf(changeHYU(c)), Collectors.counting()));

        int min = Integer.MAX_VALUE;
        for (Object num : result.keySet()) {
            min = Integer.min(Math.toIntExact(result.get(num)), min);
        }

        sb = new StringBuilder();
        if (energy == 0) {
            sb.append("Nalmeok");
        } else {
            sb.append(energy);
        }
        sb.append(System.lineSeparator());
        if (min == 1 || Integer.MAX_VALUE == min) {
            sb.append("I love HanYang University");
        } else {
            sb.append(min - 1);
        }
        System.out.println(sb);

    }

    static boolean isHYU(int a) {
        switch (a) {
            case 'H', 'Y', 'U':
                return true;
            default:
                return false;
        }
    }

    static String changeHYU(int c) {
        return String.valueOf((char) c);
    }

    private enum HYU {
        H,
        Y,
        U
    }
}

후기

스트림 없이 하면 참 쉽겠지만… 언젠가는 잘 써보고싶어서 계속 활용하면서 일단 익숙해져야할것같다.. 이번에는 스트림을 리팩토링 후에 성능이 더 느려졌는데 아마 boxing하는 비용이 더 많아지고, 중간에 changeHYU를 통해 계속 값을 더해줘서 그럴 것 같았다.

반응형

+ Recent posts