From f7eded7bfb541d7a7b96e21f9e80573c86764a68 Mon Sep 17 00:00:00 2001 From: tiny656 Date: Tue, 26 Dec 2023 18:55:50 +0800 Subject: [PATCH] add advance 1176-1179 --- .../1176_The Closest Fibonacci Number (25).py | 18 +++ .../1177_Subsequence in Substring (25).cpp | 30 ++++ .../1178_File Path (25).cpp | 66 +++++++++ .../1178_File Path (25).py | 47 ++++++ .../1179_Chemical Equation (30).cpp | 135 ++++++++++++++++++ 5 files changed, 296 insertions(+) create mode 100644 PAT (Advanced Level) Practice/1176_The Closest Fibonacci Number (25).py create mode 100644 PAT (Advanced Level) Practice/1177_Subsequence in Substring (25).cpp create mode 100644 PAT (Advanced Level) Practice/1178_File Path (25).cpp create mode 100644 PAT (Advanced Level) Practice/1178_File Path (25).py create mode 100644 PAT (Advanced Level) Practice/1179_Chemical Equation (30).cpp diff --git a/PAT (Advanced Level) Practice/1176_The Closest Fibonacci Number (25).py b/PAT (Advanced Level) Practice/1176_The Closest Fibonacci Number (25).py new file mode 100644 index 0000000..0d470fa --- /dev/null +++ b/PAT (Advanced Level) Practice/1176_The Closest Fibonacci Number (25).py @@ -0,0 +1,18 @@ +fib = [0, 1] + +count = 0 +while fib[-1] <= 10**8: + new = fib[-1] + fib[-2] + fib.append(new) + +v = int(input()) +ans, diff = -1, 10**8 +for i in range(len(fib)): + if fib[i] >= v: + if abs(fib[i] - v) < diff: + ans = fib[i] + break + else: + ans = fib[i] + diff = abs(fib[i] - v) +print(ans) diff --git a/PAT (Advanced Level) Practice/1177_Subsequence in Substring (25).cpp b/PAT (Advanced Level) Practice/1177_Subsequence in Substring (25).cpp new file mode 100644 index 0000000..a98858e --- /dev/null +++ b/PAT (Advanced Level) Practice/1177_Subsequence in Substring (25).cpp @@ -0,0 +1,30 @@ +#include +#include +using namespace std; + +int main() { + ios::sync_with_stdio(false); + string s, p; + cin >> s >> p; + + pair ans{10e5+10, ""}; + // brute force match p in s and find the shortest substring + for (int i = 0; i < s.size(); i++) { + if (s[i] != p[0]) continue; + int l = i, r = l+1; + int k = 1; + for (; r < s.size() && k != p.size(); r++) { + if (s[r] == p[k]) k++; + if (k == p.size()) break; + } + + int len = r-l+1; + if (k == p.size() && len < ans.first) { + ans.first = len; + ans.second = s.substr(l, len); + } + } + + cout << ans.second << endl; + return 0; +} \ No newline at end of file diff --git a/PAT (Advanced Level) Practice/1178_File Path (25).cpp b/PAT (Advanced Level) Practice/1178_File Path (25).cpp new file mode 100644 index 0000000..1ee2239 --- /dev/null +++ b/PAT (Advanced Level) Practice/1178_File Path (25).cpp @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#include + +using namespace std; + +unordered_map BuildChildParentMap(int n) { + unordered_map child_parent_map; + stack s; + string line, id; + + for (int i = 0; i < n; ++i) { + getline(cin, line); + int depth = line.find_first_not_of(' '); + id = line.substr(depth); + while (s.size() > depth) s.pop(); + if (!s.empty()) child_parent_map[id] = s.top(); + s.push(id); + } + return child_parent_map; +} + +// Function to trace back the path from a node to the root +string GetPath(const string& id, const unordered_map& child_parent_map) { + vector path; + string cur = id; + + while (child_parent_map.find(cur) != child_parent_map.end()) { + path.push_back(cur); + cur = child_parent_map.at(cur); + } + path.push_back("0000"); // Root ID + + string path_str; + for (auto it = path.rbegin(); it != path.rend(); ++it) { + if (it != path.rbegin()) path_str += "->"; + path_str += *it; + } + + return path_str; +} + +int main() { + ios::sync_with_stdio(false); + int n; + cin >> n; + cin.ignore(); // Ignore the newline after reading n + + auto child_parent_map = BuildChildParentMap(n); + + string queries_line; + getline(cin, queries_line); + istringstream iss(queries_line); + string query; + iss >> query; // Skip the first part, which indicates the number of queries + + while (iss >> query) { + if (child_parent_map.find(query) != child_parent_map.end() || query == "0000") cout << GetPath(query, child_parent_map) << endl; + else cout << "Error: " << query << " is not found." << endl; + } + + return 0; +} \ No newline at end of file diff --git a/PAT (Advanced Level) Practice/1178_File Path (25).py b/PAT (Advanced Level) Practice/1178_File Path (25).py new file mode 100644 index 0000000..a333709 --- /dev/null +++ b/PAT (Advanced Level) Practice/1178_File Path (25).py @@ -0,0 +1,47 @@ +# Dictionary to store child -> parent relationships +parent_dict = {} + + +def build_tree(lines): + # Stack to keep track of the current path + stack = [] + # Parse the tree structure + for line in lines: + # Count the leading spaces to determine the depth + depth = len(line) - len(line.lstrip(" ")) + # Get the ID without leading spaces + id = line.strip() + # If the stack is longer than the depth, pop elements + while len(stack) > depth: + stack.pop() + # If the stack is not empty, the last element is the parent + if stack: + parent_dict[id] = stack[-1] + # Push the current id onto the stack + stack.append(id) + + +# Function to trace back the path from a node to the root +def get_path(id): + path = [] + while id in parent_dict: + path.append(id) + id = parent_dict[id] + path.append("0000") # Root ID + return "->".join(reversed(path)) + + +n = int(input()) +lines = [] +for i in range(n): + lines.append(input()) +build_tree(lines) + +queries = input().split()[1:] +# Process the queries +for query in queries: + # Check if the ID exists in the tree + if query in parent_dict or query == "0000": + print(get_path(query)) + else: + print(f"Error: {query} is not found.") diff --git a/PAT (Advanced Level) Practice/1179_Chemical Equation (30).cpp b/PAT (Advanced Level) Practice/1179_Chemical Equation (30).cpp new file mode 100644 index 0000000..2099ed1 --- /dev/null +++ b/PAT (Advanced Level) Practice/1179_Chemical Equation (30).cpp @@ -0,0 +1,135 @@ +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +void parse_input( + vector &reactants, + vector &products, + unordered_map>> &reactions) { + + int n, m, k; + cin >> n; + reactants.resize(n); + for (int i = 0; i < n; ++i) cin >> reactants[i]; + + cin >> m; + products.resize(m); + // store products in reverse order, to reduce the time of vector::pop_back when searching + for (int i = 0; i < m; ++i) cin >> products[m-i-1]; + + cin >> k; + string line; + getline(cin, line); // ignore the newline character after k + unordered_set ignore_self_products; + for (int i = 0; i < k; ++i) { + int reactions_product; + vector reactions_reactants; + + string part; + bool next_part_is_product = false; + getline(cin, line); + stringstream ss(line); + // split the line by space, get reactants and product, store in reactions + while (getline(ss, part, ' ')) { + if (part == "+") continue; + else if (part == "->") { next_part_is_product = true; continue; } + + if (next_part_is_product) reactions_product = stoi(part); + else reactions_reactants.push_back(stoi(part)); + } + + // check if the product is the same as the reactants + reactions[reactions_product].push_back(reactions_reactants); + if (reactions_reactants.size() == 1 && *reactions_reactants.begin() == reactions_product) + ignore_self_products.insert(reactions_product); + } + + // fill in self reactions if not exist + for (int i = 0; i < m; i++) { + int product = products[i]; + if (ignore_self_products.find(product) != ignore_self_products.end()) continue; + reactions[product].push_back(vector{ product }); + } +} + +// backtracking search +void search( + vector &remain_products, + unordered_set &remain_reactants, + unordered_map>> &reactions, + vector>> &solution, + bool &is_found) { + + // if found solution, stop searching + if (is_found) return; + + // if no more products remain, got a solution, set is_found flag + if (remain_products.empty()) { + is_found = true; + return; + } + + int product = remain_products.back(); + for (auto &reactant_set : reactions[product]) { + // validation check if the reactants are all in remain_reactants + bool is_valid_reaction = true; + for (auto &reactant : reactant_set) { + if (remain_reactants.find(reactant) == remain_reactants.end()) { + is_valid_reaction = false; + break; + } + } + if (!is_valid_reaction) continue; + + // record context + for (auto &reactant : reactant_set) remain_reactants.erase(reactant); + remain_products.pop_back(); + solution.push_back({product, reactant_set}); + + // search next + search(remain_products, remain_reactants, reactions, solution, is_found); + if (is_found) return; // check point for early stop if found solution + + // back + for (auto &reactant : reactant_set) remain_reactants.insert(reactant); + remain_products.push_back(product); + solution.pop_back(); + } +} + +int main() { + ios::sync_with_stdio(false); + + vector reactants; + vector products; + unordered_map>> reactions; + + parse_input(reactants, products, reactions); + + // sort reactions by reactants order to find the 1st solution as best solution + for (auto &reaction : reactions) { + sort(reaction.second.begin(), reaction.second.end(), [&](const vector &a, const vector &b) { + for (int j = 0; j < a.size() && j < b.size(); j++) { + if (a[j] != b[j]) return a[j] < b[j]; + } + }); + } + + auto r = unordered_set(reactants.begin(), reactants.end()); + vector>> solution; + bool is_find = false; + search(products, r, reactions, solution, is_find); + + for (auto &s : solution) { + cout << setfill('0') << setw(2) << s.second[0]; + for (int i = 1; i < s.second.size(); i++) cout << " + " << setfill('0') << setw(2) << s.second[i]; + cout << " -> " << setfill('0') << setw(2) << s.first << endl; + } + + return 0; +} \ No newline at end of file