Study hard

(c++)백준 10816번: 숫자 카드 2 본문

백준/이분, 삼분탐색

(c++)백준 10816번: 숫자 카드 2

Nimgnoej 2020. 6. 24. 08:59

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

 

10816번: 숫자 카드 2

첫째 줄에 상근이가 가지고 있는 숫자 카드의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 숫자 카드에 적혀있는 정수가 주어진다. 숫자 카드에 적혀있는 수는 -10,000,000보다 크거나 같고, 10,

www.acmicpc.net

[풀이]

10815번 숫자 카드와는 다르게 상근이가 해당 숫자 카드를 몇 개 가지고 있는지 확인하는 문제였다. 

기본 이분탐색으로는 카드의 유무만 판단할 수 있기 때문에 upperbound와 lowerbound를 구하는 방식을 사용했다. 

upperbound는 찾으려는 값보다 큰 값이 처음 나오는 위치이고, lowerbound는 찾으려는 값 이상인 값이 처음 나오는 위치이다.

 

#include <iostream>
#include <algorithm>//sort
using namespace std;
#define Max 500001

int N, M;
int SNum[Max];//상근이가 가지고 있는 숫자 카드들

//찾으려는 값 이상의 수가 처음 나오는 위치 찾기
int LowerBound(int card) {
	int mid, low, high;
	low = 0;
	high = N - 1;

	while (low < high) {
		mid = (low + high) / 2;
		if (SNum[mid] >= card)
			high = mid;
		else
			low = mid + 1;
	}
	return high;
}

//찾으려는 값보다 큰 수가 처음 나오는 위치 찾기
int UpperBound(int card) {
	int mid, low, high;
	low = 0;
	high = N - 1;

	while (low < high) {
		mid = (low + high) / 2;
		if (SNum[mid] > card)
			high = mid;
		else
			low = mid + 1;
	}
	return high;
}

void solution() {
	cin >> N;
	for (int i = 0; i < N; i++) {
		cin >> SNum[i];
	}
	sort(SNum, SNum + N);

	cin >> M;
	for (int i = 0; i < M; i++) {
		int card;
		cin >> card;
		
		int lower = LowerBound(card);
		int upper = UpperBound(card);

		if (upper == N - 1 && card == SNum[N - 1])
			upper++;
		cout << upper - lower << ' ';
	}
}

int main() {
	cin.tie(0);
	ios_base::sync_with_stdio(false);
	solution();
	return 0;
}