
리뷰

https://www.acmicpc.net/problem/29811
인구 수가 중복이 되는지 여부를 알 수 없어 멀티셋을 사용하여 풀이하였다.
전역 변수
- MAX : 배열 크기의 최대값을 저장할 상수 변수
- n : 애지문에서 대운동장까지의 경로 수를 저장할 변수
- m : 대운동장에서 ITBT관까지의 경로 수를 저장할 변수
- k : 쿼리의 개수를 저장할 변수
- N : 애지문에서 대운동장까지의 경로의 인구를 저장할 배열
- M : 대운동장에서 ITBT관까지의 경로의 인구를 저장할 배열
- NV : 애지문에서 대운동장까지의 경로의 인구와 인덱스를 오름차순으로 정렬할 멀티셋
- MV : 대운동장에서 ITBT관까지의 경로의 인구와 인덱스를 오름차순으로 정렬할 멀티셋
함수
없음
문제풀이
- n, m값을 입력 받는다.
- 1 ~ n까지의 인구수를 N배열에 입력 받고, NV에는 인구수와 인덱스를 쌍을 지어 추가해 준다.
- 1 ~ m까지의 인구수를 M배열에 입력 받고, MV에는 인구수와 인덱스 + n을 쌍을 지어 추가해 준다.
- k값을 입력 받고, k번의 루프를 수행한다. 매 루프마다 변수 op에 쿼리 종류를 입력 받아준다.
- op가 U라면 변수 a, b에 인덱스와 값을 입력 받아준다.
- a이 n이하일 경우 NV에서 N[a], a값을 erase하고, N[a]를 b로 바꾼 다음 NV에 b, a를 insert해준다.
- a이 n초과일 경우 MV에서 M[a - n], a값을 erase하고, M[a - n]를 b로 바꾼 다음 MV에 b, a를 insert해준다.
- op가 L이라면 NV의 begin()의 인덱스 값과 MV의 begin()의 인덱스 값을 공백을 구분하여 출력해 준다.
트러블 슈팅
없음
참고 사항
- 가장 빠른 길이 여러가지일 경우 인덱스가 작은 값을 출력해 주어야 한다.
- 우선순위 큐를 2개를 사용하고, lazy하게 delete해주는 방법도 가능할 것 같다.
정답 코드
#include<iostream>
#include<set>
using namespace std;
const int MAX = 100001;
int n, m, k;
int N[MAX], M[MAX];
multiset<pair<int, int>> NV, MV;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
cin >> N[i];
NV.insert({ N[i], i });
}
for (int i = 1; i <= m; ++i) {
cin >> M[i];
MV.insert({ M[i], i + n });
}
cin >> k;
while (k--) {
char op; cin >> op;
if (op == 'U') {
int a, b; cin >> a >> b;
if (a <= n) {
NV.erase({ N[a], a });
N[a] = b;
NV.insert({ b, a });
}
else {
MV.erase({ M[a - n], a });
M[a - n] = b;
MV.insert({ b, a });
}
}
else {
cout << (*NV.begin()).second << " " << (*MV.begin()).second << "\n";
}
}
}
728x90
'알고리즘 공부 > C++' 카테고리의 다른 글
[G4] 백준 30827번 회의실 배정 C++ 정렬, 멀티셋, 그리디 알고리즘 (0) | 2025.03.08 |
---|---|
[P3] 백준 수열과 쿼리 20 C++ 트라이 (0) | 2025.03.08 |
[G2] 백준 1445번 일요일 아침의 데이트 C++ 다익스트라 (0) | 2025.03.07 |
[G4] 백준 24955번 숫자 이어 붙이기 C++ 너비 우선 탐색 (0) | 2025.03.06 |
[G4] 백준 12886번 돌 그룹 C++ 너비 우선 탐색 (0) | 2025.03.05 |