문제 링크: 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++] 4836: 춤  (0) 2020.07.02
[백준][C++] 1043: 거짓말  (0) 2020.06.29
[백준][C++] 1036: 36진수  (0) 2020.06.24
[백준][C++] 18119: 단어 암기  (0) 2020.06.21