Two Charts Become One ⧉
At the time of writing, this problem has a difficulty rating of 6.7 on Kattis, which qualifies as a Hard. It's fresh from the contest — I think the difficulty will even out to around a 4.5.
A fun parsing problem. Given two strings that describe hierarchical organizations (rooted trees), determine if the hierarchies are the same.
The general steps are as follows:
- Construct the hierarchy (tree) described by each string (stack-based parsing exercise)
- Ensure the head departments (roots) of the hierarchies are the same.
- DFS on one of the hierarchies, ensuring the current department is present in the other hierarchy.
_101#include <iostream>_101#include <string>_101#include <unordered_map>_101#include <set>_101#include <stack>_101_101using hierarchy = std::unordered_map<int, std::set<int>>;_101_101template <class II>_101int next_int(II& it, II& end);_101_101/**_101 * Parse a chart string of the following form:_101 * _101 * <hierarchy> ::= <department number> (<hierarchy>)*_101 * _101 * In this case, the leading (head) department in a hierarchy_101 * is in charge of all the subsequent parenthesised hierarchies._101 * _101 * For example, the chart string '11 (10) (12 (13) (17) (28))'_101 * corresponds to the following hierarchy:_101 * _101 * 11 (the head department)_101 * / \_101 * 10 12_101 * / | \ _101 * 13 17 28_101 */_101auto parse_chart (const std::string& chart_string) -> std::pair<int, hierarchy> {_101 auto it = chart_string.begin();_101 auto end = chart_string.end();_101 hierarchy org;_101 std::stack<int> roots;_101 int head = next_int(it, end);_101 roots.push(head);_101_101 while (it != end) {_101 switch (*it) {_101 case ' ': { it++; break; }_101 case '(': { it++; break; }_101 case ')': { it++; roots.pop(); break; }_101_101 // the 0-9 case_101 default: {_101 int x = next_int(it, end);_101 org[roots.top()].insert(x);_101 roots.push(x);_101 }_101 }_101 }_101_101 return {head, org};_101}_101_101int main () {_101 std::string a,b;_101 std::getline(std::cin, a);_101 std::getline(std::cin, b);_101_101 auto [r1, org1] = parse_chart(a);_101 auto [r2, org2] = parse_chart(b);_101_101 if (r1 != r2) {_101 std::cout << "No\n";_101 return 0;_101 }_101_101 std::stack<int> stk;_101 stk.push(r1);_101_101 // walk through the first hierarchy,_101 // confirming it's the same as all the other hierarchies._101 while (!stk.empty()) {_101 int r = stk.top();_101 stk.pop();_101_101 if (org1[r] != org2[r]) {_101 std::cout << "No\n";_101 return 0;_101 }_101_101 for (auto child : org1[r]) {_101 stk.push(child);_101 }_101 }_101 std::cout << "Yes\n";_101}_101_101/**_101 * Read an integer from a string iterator,_101 * advancing the iterator. We trust there's a int here._101 * */_101template <class II>_101int next_int(II& it, II& end) {_101 int x = 0;_101 while (it != end && *it >= '0' && *it <= '9') {_101 x *= 10;_101 x += *it++ - '0';_101 }_101 return x;_101}
If you found this solution helpful, consider leaving a star!