코딩 공부 연습

프로그래머스 - 숫자 게임

miffy짱 2023. 3. 30. 00:18
반응형

요즘 백준을 낮은 난이도부터 채우면서, 블로그에 남길만한 문제가 별로 없다. 이번에 스터디를 하면서, 프로그래머스 스킬 테스트를 해보게 되었는데, 마침 이번 스터디에서 스킬 테스트에서 이 문제를 풀어보게 되었고, 이문제만 풀고 두번째는 풀지 못하면서 결국 통과하지 못했다..!! 아쉬워라

 

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

 

문제를 이해해 보자.

A 팀에서 어떤 순서로 숫자를 출전시킬지 알고 있는 상황에서 B 팀은 자신들의 숫자를 조합해 가장 많이 이길 수 있는 경우를 찾는 것이 목적이다. a,b 는 10만개 까지 받을 수 있고, 각 값은 1000000000 이하의 자연수이다.

 

이 문제를 해결하기 위해, 정렬한 후 for 문으로 대조해 가면서 값을 빼주고자 하였는데, 이렇게 하면 시간 초과가 날 것이 너무 당연했다. 그래서 생각한 다른 방법은, 스택에 작은 값 순서대로 넣으며 a 와 대조해 pop 시키며 진행하는 것이었다.

 

바로 코드를 보자!

#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include <stack>

using namespace std;

int solution(vector<int> A, vector<int> B) {
    int answer = -1;
    vector<pair<int,int>> total;
    for(int i = 0; i < A.size(); i++)
    {
        total.push_back({A[i], 0});
        total.push_back({B[i], 1});
    }
    sort(total.begin(), total.end());
    deque<int> st; 
    int cnt = 0;
    for (int i = 0; i < total.size(); i++)
    {
        if (total[i].second == 1) //B팀
        {
            if (st.size() != 0)
            {
                int comp = st.back();
                if (comp != total[i].first)
                {
                    st.pop_back();
                   cnt++; 
                }  
            }
        }
        else
        {
            st.push_front(total[i].first); //A팀
        }
    }
    answer = cnt;
    cout<<cnt;
    return answer;
}

이렇게, 우선 A와 B 를 모두 하나의 배열에 담고 작은 순으로 정렬하였다.

이제 그 AB 통합배열을 순회하면서, B의 숫자일 경우에, 디큐에 집어넣지 않을것이고, A일 경우에만 무조건 디큐에 집어넣을 것이다.

그렇다면, B인 숫자를 만났을 때 디큐에 가장 최근에 들어간 값과 대소를 비교했을 때 같거나 더 큰 경우밖에 없을 것이다.

만약 더 크다면 이기는 경우이니 카운트를 증가해주고, 디큐의 back 에 있던 값을 pop 해준다. 같을 때에는 그냥 진행해준다.

 

이게 다다!!