
B팀이 A팀의 출전 순서를 보고 승점을 최대로 얻는 방법을 찾는 문제다. 핵심은 "이길 수 있으면 가장 근소한 차이로 이기고, 이길 수 없으면 가장 작은 패를 버리는 것"이다. 이 최대 10만이라 탐색은 불가능하며, 정렬(Sorting)과 투 포인터를 활용한 그리디(Greedy) 알고리즘으로 에 해결해야 한다.
A, B의 길이는 최대 100,000이다.vector의 erase 함수를 써서 사용한 카드를 지우는 방식을 떠올렸다.i) 확인한다.head)가 A의 카드(i)보다 크다면? 승리! 승점 챙기고 head 인덱스 증가.tail)를 소모해서 강한 카드를 아낀다.#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int solution(vector<int> A, vector<int> B) {
int answer = 0;
int n = A.size();
int m = B.size();
// 투 포인터 초기화:
// head는 현재 B팀의 가장 큰 카드, tail은 가장 작은 카드를 가리킴
int head = 0, tail = m - 1;
// 내림차순 정렬
// 큰 수부터 비교해야 '도저히 못 이기는 상황'을 빠르게 판단 가능
sort(A.rbegin(), A.rend());
sort(B.rbegin(), B.rend());
// A팀의 카드 순회
for (int i = 0; i < n; i++) {
// 더 이상 사용할 카드가 없거나 포인터가 교차되면 종료 (방어 코드)
if (head > tail) break;
// B의 최강 카드로 A의 현재 카드를 이길 수 있는가?
if (A[i] < B[head])
{
// 이긴다: 승점 획득 후 다음 강한 카드로 이동
answer++;
head++;
}
else
{
// 못 이긴다: 가장 약한 카드(tail)를 버림
tail--;
}
}
return answer;
}
vector를 수정하지 않고, 인덱스(head, tail)만 조절하여 논리적으로만 카드를 제거했다. 이렇게 하니 시간 복잡도 문제도 해결되고 코드도 훨씬 깔끔해졌다.sort를 할 때 A도 같이 정렬해도 되는지 헷갈렸는데, 어차피 B는 A의 '어떤 숫자'를 상대하느냐가 중요하지 순서는 중요하지 않다는 점을 깨달았다. 즉, A를 정렬해서 비교해도 최댓값을 구하는 데는 문제가 없다.| 항목 | 내용 |
|---|---|
| 유형 | Greedy (탐욕법) |
| 체감 난이도 | 하 (문제 이해 후 전략만 세우면 구현은 쉬움) |
| 복잡도 | 시간: , 공간: |
| 새로 배운 것 | sort(v.rbegin(), v.rend())로 내림차순 정렬하기, 투 포인터로 삭제 연산 대체하기 |