※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 18559번 문제인 부모님께 큰절 하고이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/18859
18859번: 부모님께 큰절 하고
Agent 욱제는 훈련소로 떠나기 전, 부모님께 큰절을 올렸다. 어릴 적, 욱제의 부모님은 욱제에게 말하곤 했다. "욱제야, 꼭 기억하렴. Agent의 큰절은 예술적이어야 한단다." 하지만, 오늘 부모님은
www.acmicpc.net
이 문제에서는, 주어진 N개의 수로 어떤 1<k<N에 대하여 첫번째부터 k번째 수까지는 감소하는 등차수열, k번째부터 N번째 수까지는 증가하는 등차수열이 되게 할 수 있는지의 여부를 묻고 있다.
위와 같이 수들을 배치할 수 있다면 k번째 수는 N개의 수중 가장 작은 수일 수밖에 없다는 점을 확인하자.
또한, 두번째로 작은 수가 등차수열의 일부이려면 그 수와 가장 작은 수와의 차이만큼이 공차인 등차수열이 하나 있어야하므로, 가장 작은 수가 초항, 두번째로 작은 수가 두번째 항인 (중간에 항이 빠지지 않은) 등차수열에 해당하는 수를 N개의 수에서 지울 수 없을 때까지 지워나가자. 단, 마지막으로 지워진 수는 또다른 등차수열에 포함시켜서 이어나갈 가능성이 있으니 일단 저장해두자.
가장 작은 수와 두번째로 작은 수가 같다면, 공차가 0이므로 조건에 맞는 수열을 만들 수 없다는 점에 신경쓰자.
이제 남은 수가 (마지막으로 지워진 수)를 포함하거나 포함하지 않은 상태로 등차수열을 이룬다면 "Yes", 아니면 "No"를 출력하면 문제를 해결할 수 있다. (이것의 증명은 간단하므로 생략한다.)
글쓴이는 multiset 자료구조를 이용하여 문제를 해결하였으나, 더 좋은 방법이 있을 거라고 생각된다.
아래는 제출한 소스코드이다.
#include <iostream>
#include <set>
using namespace std;
multiset<int> st;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int N; cin >> N;
while (N--) {
int x; cin >> x;
st.insert(x);
}
int bottom = *st.begin();
st.erase(st.begin());
int diff = *st.begin() - bottom;
int current = *st.begin();
if (diff == 0) {
cout << "No";
return 0;
}
int lastdeleted;
while (!st.empty()) {
auto iter = st.find(current);
if (iter != st.end()) {
st.erase(iter);
lastdeleted = current;
current += diff;
}
else break;
}
if (st.empty()) {
cout << "Yes";
return 0;
}
else if (st.size() == 1) {
cout << "Yes";
return 0;
}
diff = *st.begin() - bottom;
current = *st.begin();
int cnt = 0;
while (!st.empty()) {
auto iter = st.find(current);
if (iter != st.end()) {
current += diff;
cnt++;
}
else break;
}
if (cnt == st.size()) {
cout << "Yes";
return 0;
}
st.insert(lastdeleted);
diff = *st.begin() - bottom;
current = *st.begin();
cnt = 0;
while (!st.empty()) {
auto iter = st.find(current);
if (iter != st.end()) {
current += diff;
cnt++;
}
else break;
}
if (cnt == st.size()) cout << "Yes";
else cout << "No";
}
'BOJ' 카테고리의 다른 글
[BOJ 11695 // C++] 표 게임 (0) | 2021.07.10 |
---|---|
[BOJ 3687 // C++] 성냥개비 (0) | 2021.07.09 |
[BOJ 13560 // C++] 축구 게임 (0) | 2021.07.07 |
[BOJ 16566 // C++] 카드 게임 (0) | 2021.07.06 |
[BOJ 17409 // C++] 증가 수열의 개수 (0) | 2021.07.05 |