
AtCoder Beginner Contest 206 - A부터 D까지 업솔빙
falconlee236
·2021. 12. 19. 15:27
AtCoder Beginner Contest 206 A부터 D까지 업솔빙
진짜 아쉬웠던 대회, 내 수준은 엣코더를 6번째 하면서 D번까지 풀면 실력이 오른거고 D번을 못풀면 실력이 아직 재자리라고 느끼는데 이번에는 접근 방법은 다 생각했는데 구현 방식을 몰라서 못풀었다. 이런 작동을 하는 효율적인 알고리즘이 무엇일까? 라는 생각의 답을 찾기 위해서는 다양한 variation의 문제를 풀면서 경험을 쌓는 수밖에 없다.
이번 대회를 참여하면서 배운 것은
- Disjoint-Set(분리집합)의 find함수의 쓰임새
문제 옆에 붙어있는 난이도는 Atcoder Problems 에서 추정한 것으로 작성했다는 것을 미리 알린다.
A - Maxi-Buying (*5)
접기/펼치기
문제 설명
Atcoder 공화국에서는 소비세가 8%이다.
이 나라의 에너지 음료 상점은 에너지 음료를 세금을 제외하고
세금을 포함하면 가격은
만약 세금을 포함한 가격이
제약
- 모든 입력은 정수이다.
문제 해설
정답 코드
#include <iostream>
using namespace std;
int main() {
ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n; cin >> n;
int res = n * 1.08;
cout << (res < 206 ? "Yay!" : (res > 206 ? ":(" : "so-so"));
return 0;
}
B - Savings (*14)
접기/펼치기
문제 설명
진수는 빈 돼지저금통을 가지고 있다.
각 밤마다 진수는 돈이 얼마나 있는지 확인한다.
각 날 밤에 진수가 돼지저금통을 확인했을 때
제약
- 모든 입력은 정수로 이루어져 있다.
문제 해설
정답 코드
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() {
ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n; cin >> n;
int ans = 0, res = 0;
for(int i = 1; res < n; i++){
res += i;
ans++;
}
cout << ans;
return 0;
}
C - Swappable (*171)
접기/펼치기
문제 설명
제약
- 모든 값은 정수로 주어진다.
문제 해설
이전에 풀었던 ABC200-C와 아주 유사한 문제이다. 결국
전체 조합인
이때
정답 코드
#include <iostream>
#include <map>
using namespace std;
int main() {
ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
long long n; cin >> n;
int arr[n];
map<int, long long> mp;
long long res = n * (n - 1) / 2;
for(int i = 0; i < n; i++){
int num; cin >> num;
mp[num]++;
}
for(auto x : mp) res -= (x.second * (x.second - 1) / 2LL);
cout << res;
return 0;
}
D - KAIBUNsyo (*879)
접기/펼치기
문제 설명
- 양수로 이루어진 순서쌍
을 선택하고, 에 있는 모든 를 로 바꾼다.
우리는
제약
- 모든 입력은 정수로 주어진다.
문제 해설
서로 양 끝부터 비교해서 양 끝이 같으면 바꿀 필요가 없다. 그런데 양 끝이 서로 다르면 두 수 중 하나는 무조건 바꿔야하는데, 이때
그렇기 때문에 이 문제를
즉 두 배열의 원소가 나타났을 때 각 원소의 find를 한 반환값이 최종적으로 이 수가 변하게 된 수이기 때문에 이 값을 비교해서 서로 다르면 한 원소가 다른 한 원소의 부모로 들어가게 가리키면 된다. 그러면 다음번에 같은 상황이 나오면 이때는 서로 부모가 같이 때문에 서로 같은 값을 가지게 되서 펠린드롬 조건을 충족한다. 서로 다르면 답을 1 증가시키는 것도 잊지말자.
정답 코드
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int root[200001];
int find(int x){
return (root[x] == x ? x : root[x] = find(root[x]));
}
int main() {
ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n; cin >> n;
for(int i = 0; i <= 200001; i++) root[i] = i;
int arr[n];
for(int& i : arr) cin >> i;
int ans = 0;
for(int i = 0; i < n / 2; i++){
int u = find(arr[i]), v = find(arr[n - i - 1]);
if(u == v) continue;
ans++;
root[u] = v;
}
cout << ans;
return 0;
}
'알고리즘 > atcoder' 카테고리의 다른 글
AtCoder Beginner Contest 209 - A부터 D까지 업솔빙 (0) | 2021.12.26 |
---|---|
AtCoder Beginner Contest 208 A부터 D까지 업솔빙 (0) | 2021.12.24 |
AtCoder Beginner Contest 205 - A부터 D까지 업솔빙 (0) | 2021.12.16 |
AtCoder Beginner Contest 204 - A부터 D까지 업솔빙 (0) | 2021.11.27 |
AtCoder Beginner Contest 202 - A부터 D까지 업솔빙 (0) | 2021.11.22 |