문제 |
10816번: 숫자 카드 2
첫째 줄에 상근이가 가지고 있는 숫자 카드의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 숫자 카드에 적혀있는 정수가 주어진다. 숫자 카드에 적혀있는 수는 -10,000,000보다 크거나 같고, 10,
www.acmicpc.net
코드 1 (이분탐색) |
#include <iostream>
#include <algorithm>
using namespace std;
vector<int> v;
int getFrequency(int num) {
return (int) (upper_bound(v.begin(), v.end(), num) - lower_bound(v.begin(), v.end(), num));
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
v.resize(n);
for (int &i: v) cin >> i;
sort(v.begin(), v.end());
int m;
cin >> m;
while (m--) {
int num;
cin >> num;
cout << getFrequency(num) << ' ';
}
return 0;
}
설명 |
벡터에 n개의 정수를 입력받은 후 정렬한다.
그 후, 찾으려 하는 정수마다 std::lower_bound(이상인 최초의 값)과
std::upper_bound(초과인 최초의 값)의 인덱스 차이를 출력하면 된다.
int lowerBound(int num) {
int low = 0;
int high = n;
while (low != high) {
int mid = (low + high) / 2;
if (v[mid] < num) low = mid + 1;
else high = mid;
}
return low;
}
int upperBound(int num) {
int low = 0;
int high = n;
while (low != high) {
int mid = (low + high) / 2;
if (v[mid] <= num) low = mid + 1;
else high = mid;
}
return low;
}
lower_bound, upper_bound는 위와 같이 구현할 수 있다.
코드 2 (HashMap) |
#include <iostream>
#include <unordered_map>
using namespace std;
unordered_map<int, int> mp;
void updateFrequency(int num) {
if (!mp.contains(num)) mp[num] = 1;
else mp[num]++;
}
int getFrequency(int num) {
if (!mp.contains(num)) return 0;
return mp[num];
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
while (n--) {
int num;
cin >> num;
updateFrequency(num);
}
int m;
cin >> m;
while (m--) {
int num;
cin >> num;
cout << getFrequency(num) << ' ';
}
return 0;
}
설명 |
HashMap인 std::unordered_map을 사용하면 삽입과 탐색 연산을 평균적으로 O(1)에 할 수 있어 굉장히 빠르다.
TreeMap인 std::map을 사용해도 통과는 되지만 삽입과 탐색 연산이 O(log n)이라 unordered_map 보다는 느리다.
코드 3 (Counting Sort) |
#include <iostream>
#define MIN_NUM (-10000000)
#define MAX_NUM 10000000
using namespace std;
int arr[MAX_NUM - MIN_NUM + 1];
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
while (n--) {
int num;
cin >> num;
arr[num - MIN_NUM]++;
}
int m;
cin >> m;
while (m--) {
int num;
cin >> num;
cout << arr[num - MIN_NUM] << ' ';
}
return 0;
}
설명 |
정확히 말하면 Counting Sort를 그대로 적용한 것은 아니고 아이디어만 가져온 것이다.
2천만+1개 사이즈의 배열을 만든 후 입력받은 숫자에 해당하는 위치의 값을 올린다.
메모리 제한은 256MB인데, 2천만 * 4byte (int) = 8천만 byte = 약 80MB이므로 충분히 가능하다.
'PS > BOJ' 카테고리의 다른 글
[C++] BOJ (백준) 10845 : 큐 (0) | 2023.03.05 |
---|---|
[C++] BOJ (백준) 10828 : 스택 (0) | 2023.03.05 |
[C++] BOJ (백준) 10814 : 나이순 정렬 (0) | 2023.03.05 |
[C++] BOJ (백준) 10773 : 제로 (0) | 2023.03.05 |
[C++] BOJ (백준) 10250 : ACM 호텔 (0) | 2023.03.05 |