본문 바로가기

프로그래머스

2024 KAKAO WINTER INTERNSHIP - N + 1 카드게임 <JAVA>

https://school.programmers.co.kr/learn/courses/30/lessons/258707

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제 

 

1~n 개 사이의 수가 적힌 카드 , target Number 는 n + 1

 

1라운드부터 게임이 시작된다 - > 각 라운드 마다 카드 두장을 뽑아 / 남은 카드가 없다면 게임이 종료

 

target 이 되면 ? 타겟이 될 두장을 내고 다음 라운드를 진행함 ->  최대 몇 라운드까지 진행되는지 구한다

 

뽑은 카드 는 Coin 1개를 소비하여 가져 올 수 있으며, Coin을 소모하지 않고 그냥 버릴 수 있다.

 

Case 1 : 가지고 있는 카드에서 target 이 만들어 지는 경우

Case 2 : 다음 뽑은 카드에서의 조합으로 해결 

    Case 2.1 : 보유중인 카드 1장 + 새로 뽑은 카드 1장 조합 - Coin 1개 소모

    Case 2.2 : 새로 뽑은 카드 2장 조합 - Coin 2개 소모

 

 

 

 

아이디어

보유 하고 있는 카드를 저장할 Set , 나중에 뽑을 카드 Set 을 설정해서 저장하고 위의 케이스 3개를 따져가면서 라운드를 진행한다.

 

 

코드 

import java.util.*;

// 게임은 1라운드부터 시작되며, 각 라운드가 시작할 때 카드를 두 장 뽑습니다
//카드 뭉치에 남은 카드가 없다면 게임을 종료
//뽑은 카드는 카드 한 장당 동전 하나를 소모해 가지거나, 동전을 소모하지 않고 버릴 수 있습니다.
//1. 카드에 적힌 수의 합이 n+1이 되도록 카드 두 장을 내고 다음 라운드로 진행
//1 이 불가능하다면 ?  -> 
class Solution {
    public int solution(int coin, int[] cards) {
        int answer = 0;
        
        HashSet<Integer> now = new HashSet<>(); //가지고 있는 카드
        HashSet<Integer> next = new HashSet<>(); //나중에 뽑을 카드 (2장)
        
        int len = cards.length;
        int target = len + 1;//target 이 되면 두장을 내고 다음 라운드 진행
        int index = len/3; // 뽑을 인덱스
        
        for(int i=0; i<index; i++) {
            now.add(cards[i]); // 처음 4장
        }
        
        while (true) {
            answer++;
            if(index >= len) break;
            
            next.add(cards[index]);
            next.add(cards[index+1]);
            index+=2;
            
            boolean flag = false;
            //case 1 가지고 있는 카드에서 target 이 만들어지는 경우
            for(int card : now) {
                if(now.contains(target - card)) {
                    now.remove(card);
                    now.remove(target-card);
                    flag = true;
                    break;
                }
            }
            //다음 뽑은 카드에서의 조합으로 해결해야해
            if(!flag) {
                //case 2 가지고 있는 카드 1장 + 새로 뽑은 카드 1장 조합
                if(coin > 0) { // 코인이 있을때? 1개 소모해야하기 떄문에 0보단 커야함
                    for(int card : now) {
                        if(next.contains(target - card)) {
                            coin--;
                            now.remove(card);
                            next.remove(target - card);
                            flag = true;
                            break;
                        }
                    }
                }
            }
            
            //case 3 새로 뽑은 카드 2장 조합
            if(!flag) {
                if(coin > 1) { //코인 2개를 써서 추가 카드를 모두 뽑아야함
                    for(int card: next) {
                        if(next.contains(target - card)) {
                            coin -= 2;
                            next.remove(card);
                            next.remove(target - card);
                            flag = true;
                            break;
                        }
                    }
                }
            }
            if(!flag) {
                break;
            }
         }

        return answer;
    }
}