문제 링크: https://www.acmicpc.net/problem/4836
좀 귀찮은 문제입니다..
일단 한 줄을 공백을 delimiter로 분리해줍니다. 일단 여기서부터 귀찮습니다;; stringstream을 만들어서 vector에 잘 분리해줍니다.
이 때 저는 굳이; dip=1, jiggle=2, twirl=3 이런식으로 번호를 매겨놔서 bimap으로 왔다갔다 할 수 있게 했는데 이렇게 안해도 충분히 푸니까 그냥 string 그대로 나누는걸 추천합니다. 나눈 다음에는 그냥 쭉 rule 체크를 해주면 됩니다.
rule이 여러개 위반됐을 때 form errors K(1), K(2), ..., K(N-1) and K(N): 이런식으로 출력을 해줘야 하는데 이거 역시 귀찮습니다.
주의할점은 춤이 문제에 써있는 6종류만 나오는 게 아니고 아무거나 나올 수 있는 점 유의하셔야 합니다. map을 안쓰면 신경 안써도 되긴 합니다 ㅠ
#pragma GCC optimize ("Ofast")
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
map<string, int> m;
map<int, string> m_r;
m["dip"] = 1;
m["jiggle"] = 2;
m["twirl"] = 3;
m["clap"] = 4;
m["stomp"] = 5;
m["hop"] = 6;
m_r[1] = "dip";
m_r[2] = "jiggle";
m_r[3] = "twirl";
m_r[4] = "clap";
m_r[5] = "stomp";
m_r[6] = "hop";
int word_counter = 6;
string line;
while (getline(cin, line)) {
bool broken[5] = {};
vector<int> dances;
istringstream iss(line);
for (string s; iss >> s;) {
if (m.find(s) != m.end()) {
dances.push_back(m[s]);
}
else {
m_r[++word_counter] = s;
dances.push_back(word_counter);
}
}
auto sz = dances.size();
vector<bool> dip_err(sz);
// 1.
for (int i = 0; i < sz; ++i) {
if (dances[i] == m["dip"]) {
if (!((i-1>=0 && dances[i-1]==m["jiggle"])
|| (i-2>=0 && dances[i-2]==m["jiggle"])
|| (i+1<sz && dances[i+1]==m["twirl"]))) {
broken[0] = true;
dip_err[i] = true;
}
}
}
// 2.
if (!(sz >= 3 && dances[sz - 1] == m["clap"]
&& dances[sz - 2] == m["stomp"]
&& dances[sz - 3] == m["clap"]))
broken[1] = true;
// 3.
if (find(dances.begin(), dances.end(), m["twirl"]) != dances.end()
&& find(dances.begin(), dances.end(), m["hop"]) == dances.end())
broken[2] = true;
// 4.
if (dances[0] == m["jiggle"])
broken[3] = true;
// 5.
if (find(dances.begin(), dances.end(), m["dip"]) == dances.end())
broken[4] = true;
int broken_cnt = accumulate(broken, broken + 5, 0);
if (broken_cnt == 0) {
cout << "form ok: " << line << '\n';
}
else if (broken_cnt == 1) {
int broken_idx;
for (int i = 0; i < 5; ++i)
if (broken[i])
broken_idx = i;
cout << "form error " << broken_idx + 1 << ": ";
for (int i = 0; i < sz; ++i) {
if (dances[i] == m["dip"] && dip_err[i])
cout << "DIP";
else
cout << m_r[dances[i]];
if (i != sz - 1) cout << ' ';
}
cout << '\n';
}
else if (broken_cnt >= 2) {
cout << "form errors ";
for (int i = 0; i < 5; ++i) {
if (broken[i]) {
cout << i + 1;
--broken_cnt;
if (broken_cnt >= 2)
cout << ", ";
else if (broken_cnt == 1)
cout << " and ";
}
}
cout << ": ";
for (int i = 0; i < sz; ++i) {
if (dances[i] == m["dip"] && dip_err[i])
cout << "DIP";
else
cout << m_r[dances[i]];
if (i != sz - 1) cout << ' ';
}
cout << '\n';
}
}
return 0;
}
좀 다듬고싶은데 귀찮아서 포기하겠습니다. 지금 보니 굳이 map을 쓸 필요가 없네요.
난이도가 브론즈2로 돼있는데 흐음 글쎄요 제 생각엔 오지게 귀찮은 점을 감안하면 실버 5정도를 주고 싶습니다.
반응형
'Online Judge > 백준' 카테고리의 다른 글
[백준][C++] 2866: 문자열 잘라내기 (0) | 2020.07.04 |
---|---|
[백준][C++] 1089: 엘리베이터 (0) | 2020.07.03 |
[백준][C++] 1043: 거짓말 (0) | 2020.06.29 |
[백준][C++] 1036: 36진수 (0) | 2020.06.24 |
[백준][C++] 18119: 단어 암기 (0) | 2020.06.21 |