-
Notifications
You must be signed in to change notification settings - Fork 71
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
296 additions
and
0 deletions.
There are no files selected for viewing
18 changes: 18 additions & 0 deletions
18
PAT (Advanced Level) Practice/1176_The Closest Fibonacci Number (25).py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
30 changes: 30 additions & 0 deletions
30
PAT (Advanced Level) Practice/1177_Subsequence in Substring (25).cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#include <iostream> | ||
#include <vector> | ||
using namespace std; | ||
|
||
int main() { | ||
ios::sync_with_stdio(false); | ||
string s, p; | ||
cin >> s >> p; | ||
|
||
pair<int, string> 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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
#include <iostream> | ||
#include <string> | ||
#include <vector> | ||
#include <stack> | ||
#include <unordered_map> | ||
#include <sstream> | ||
|
||
using namespace std; | ||
|
||
unordered_map<string, string> BuildChildParentMap(int n) { | ||
unordered_map<string, string> child_parent_map; | ||
stack<string> 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<string, string>& child_parent_map) { | ||
vector<string> 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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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.") |
135 changes: 135 additions & 0 deletions
135
PAT (Advanced Level) Practice/1179_Chemical Equation (30).cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
#include <iostream> | ||
#include <iomanip> | ||
#include <sstream> | ||
#include <vector> | ||
#include <algorithm> | ||
#include <unordered_map> | ||
#include <unordered_set> | ||
using namespace std; | ||
|
||
void parse_input( | ||
vector<int> &reactants, | ||
vector<int> &products, | ||
unordered_map<int, vector<vector<int>>> &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<int> ignore_self_products; | ||
for (int i = 0; i < k; ++i) { | ||
int reactions_product; | ||
vector<int> 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<int>{ product }); | ||
} | ||
} | ||
|
||
// backtracking search | ||
void search( | ||
vector<int> &remain_products, | ||
unordered_set<int> &remain_reactants, | ||
unordered_map<int, vector<vector<int>>> &reactions, | ||
vector<pair<int, vector<int>>> &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<int> reactants; | ||
vector<int> products; | ||
unordered_map<int, vector<vector<int>>> 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<int> &a, const vector<int> &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<int>(reactants.begin(), reactants.end()); | ||
vector<pair<int, vector<int>>> 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; | ||
} |