https://www.acmicpc.net/problem/19585
19585번: 전설
Sogang ICPC Team에는 색상 이름과 닉네임의 순서로 이여서 팀명을 지으면 ICPC 리저널에서 수상할 수 있다는 전설이 있다. 색상 이름들과 닉네임들이 주어질 때, Q개의 팀에 대해 다음 리저널에서 수
www.acmicpc.net
풀이
- 입력받은 팀명의 앞에서부터 color 와 매치되는 인덱스들 체크
- 팀명의 뒤에서부터 name 과 매치되는 인덱스들 체크
- color 매치되는 인덱스 + 1 = name 과 매치되는 인덱스 이면 color + name 팀명
코드
- MLE 피하기 위해 map 사용한 Trie 구조체 사용
#include <bits/stdc++.h> using namespace std; #define all(v) (v).begin(), (v).end() #define rall(v) (v).rbegin(), (v).rend() struct Trie { bool isTerminal; map<char, Trie*> children; Trie() { isTerminal = false; } ~Trie() { for (auto& e: children) { delete e.second; } children.clear(); } }; void insert(Trie* root, string key) { Trie* tmp = root; for (auto e: key) { if (tmp -> children.find(e) == tmp -> children.end()) { tmp -> children[e] = new Trie(); } tmp = tmp -> children[e]; } tmp -> isTerminal = true; } void insert_rev(Trie* root, string key) { Trie* tmp = root; for (int i = key.size() - 1; i >= 0; --i) { if (tmp -> children.find(key[i]) == tmp -> children.end()) { tmp -> children[key[i]] = new Trie(); } tmp = tmp -> children[key[i]]; } tmp -> isTerminal = true; } void check(Trie* root, vector<int>& checked, string& key) { auto cur = root; for (int i = 0; i < key.size(); ++i) { if (cur -> children.find(key[i]) == cur -> children.end()) return; cur = cur -> children[key[i]]; if (cur -> isTerminal) checked[i] = true; } } void check_rev(Trie* root, vector<int>& checked, string& key) { auto cur = root; for (int i = key.size() - 1; i >= 0; --i) { if (cur -> children.find(key[i]) == cur -> children.end()) return; cur = cur -> children[key[i]]; if (cur -> isTerminal) checked[i] = true; } } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int N, C, Q; cin >> C >> N; Trie* color = new Trie(); Trie* name = new Trie(); for (int i = 0; i < C; ++i) { string s; cin >> s; insert(color, s); } for (int i = 0; i < N; ++i) { string s; cin >> s; insert_rev(name, s); } cin >> Q; while (Q--) { string ss; cin >> ss; vector<int> checked1(ss.size(), 0); vector<int> checked2(ss.size(), 0); check(color, checked1, ss); check_rev(name, checked2, ss); bool yes = false; for (int i = 0; i < ss.size() - 1; ++i) { if (checked1[i] == 1 && checked2[i + 1] == 1) { yes = true; break; } } if (yes) { cout << "Yes\n"; } else { cout << "No\n"; } } }
728x90
'PS > BOJ' 카테고리의 다른 글
백준 2316번: 도시 왕복하기 2 (0) | 2022.02.20 |
---|---|
백준 13537번: 수열과 쿼리 1 (0) | 2022.02.19 |
백준 1126번: 같은 탑 (0) | 2022.02.18 |
백준 11377번: 열혈강호 3 (0) | 2022.02.18 |
백준 4225번: 쓰레기 슈트 (0) | 2022.02.12 |