문제
- 문제 링크
BOJ 25181 - Swap the elements
길이 N의 수열 An이 주어진다.
이 수열에 대해, 서로 다른 두 원소를 골라 위치를 바꾸는 연산을 원하는 만큼 수행 후 수열 Bn을 만드려고 할 때,
모든 Bi에 대해 Ai≠Bi인 수열 Bn을 구해보자.
TL : 1 sec, ML : 1024 MB
1≤N≤5,000 1≤Ai≤100,000
알고리즘 분류
- 애드 혹(ad_hoc)
- 해 구성하기(constructive)
풀이
곰곰이 생각해보면, 수열 Bn을 만들 수 없는 조건은 쉽게 도출할 수 있다.
가장 많이 등장한 수를 x라 할 때, count(x)>⌊N2⌋ 라면 조건을 만족하는 Bn은 존재할 수 없다.
비둘기집 원리에 의해 Ai=Bi 인 x가 반드시 존재하게 되기 때문이다.
위를 적절히 판단 했다면, 이제 Bn이 반드시 존재하는 상황에서 어떤식으로 구성할 지 생각해보자.
사실 이것도 나이브하게 보면 O(N2) 풀이를 쉽게 떠올려 볼 수 있다.
임의의 위치 bi,bj에 대해, ai≠bj 와 aj≠bi 를 동시에 만족 한다면 swap이 가능 하다는 것을 이용하면 된다.
다행히 N≤5,000 이므로 O(N2)도 정해로 치도록 출제 하신 것 같다.
그렇게 최적화를 생각하지 않고 아래 코드로 AC를 받은 후 다른 사람들의 풀이를 구경 했는데, 비교적 간단하게 O(NlogN) 풀이를 구성할 수 있음을 깨달았다.
우선순위 큐를 이용해 원소 개수순으로 짝지어주거나, 정렬 후 x+⌊N+12⌋ 번째 원소와 바꿔주는 등..
차라리 처음부터 N≤105 정도 됐다면 좀 더 고민해봤을 듯 싶다.
전체 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #include<bits/stdc++.h> using namespace std; unordered_map <int, int> M; int a[5001], b[5001]; int main() { int n; cin >> n; for (int i(1); i <= n; i++) if (cin >> a[i]; ++M[a[i]] > n >> 1) cout << -1, exit(0); memcpy(b, a, sizeof a); for (int i(1); i <= n; i++) for (int j(1); a[i] == b[i] && j <= n; j++) if (b[j] ^ a[i] && b[i] ^ a[j]) swap(b[i], b[j]); for (int i(1); i <= n; cout << b[i++] << ' '); } | cs |
comment
끝
'Problem Solving > Baekjoon Online Judge (Gold)' 카테고리의 다른 글
백준 28131 - K-지폐 (C++) (0) | 2023.05.29 |
---|---|
백준 28127 - 숫자탑과 쿼리 (C++) (0) | 2023.05.29 |
백준 28071 - 승형이의 사탕 사기 (C++) (0) | 2023.05.25 |
백준 28082 - 기계오리 연구 (C++) (0) | 2023.05.23 |
백준 27892 - 특별한 큰 분수 (C++) (0) | 2023.05.22 |