125 lines
3.3 KiB
C++
125 lines
3.3 KiB
C++
#include <iostream>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
using namespace std;
|
|
|
|
unordered_map<char, unsigned long long> get_count_after_reaction(unordered_map<string, char> reactions, string pair, int reaction_iterations);
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
string polymer;
|
|
getline(cin, polymer);
|
|
|
|
unordered_map<string, char> reactions;
|
|
|
|
string line;
|
|
getline(cin, line);
|
|
while(getline(cin, line))
|
|
{
|
|
reactions[line.substr(0,2)] = line[line.size()-1];
|
|
}
|
|
|
|
unordered_map<char, unsigned long long> counts;
|
|
for(int i = 0; i < polymer.size(); i++)
|
|
{
|
|
counts[polymer[i]] = 0;
|
|
}
|
|
|
|
for(int i = 0; i < polymer.size(); i++)
|
|
{
|
|
counts[polymer[i]]++;
|
|
}
|
|
|
|
for(int i = 0; i < polymer.size()-1; i++)
|
|
{
|
|
string pair = polymer.substr(i,2);
|
|
unordered_map<char, unsigned long long> pair_counts = get_count_after_reaction(reactions, pair, 10);
|
|
|
|
for(auto &it : pair_counts)
|
|
{
|
|
if (!counts.contains(it.first))
|
|
{
|
|
counts[it.first] = 0;
|
|
}
|
|
|
|
counts[it.first] += it.second;
|
|
}
|
|
}
|
|
|
|
vector<unsigned long long> counts_list;
|
|
for (auto &it : counts)
|
|
{
|
|
cout << it.first << " " << it.second << endl;
|
|
counts_list.push_back(it.second);
|
|
}
|
|
|
|
sort(counts_list.begin(), counts_list.end());
|
|
|
|
cout << counts_list[counts_list.size()-1]-counts_list[0] << endl;
|
|
}
|
|
|
|
unordered_map<char, unsigned long long> get_count_after_reaction(unordered_map<string, char> reactions, string pair, int reaction_iterations)
|
|
{
|
|
static unordered_map<string, vector<unordered_map<char, unsigned long long>>> reaction_cache;
|
|
|
|
if (0 == reaction_iterations)
|
|
{
|
|
return unordered_map<char, unsigned long long>();
|
|
}
|
|
|
|
if (!reaction_cache.contains(pair))
|
|
{
|
|
reaction_cache[pair] = vector<unordered_map<char, unsigned long long>>();
|
|
}
|
|
|
|
if (reaction_cache[pair].size() >= reaction_iterations)
|
|
{
|
|
if (reaction_cache[pair][reaction_iterations-1].size() != 0)
|
|
{
|
|
return reaction_cache[pair][reaction_iterations-1];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
unsigned int old_size = reaction_cache[pair].size();
|
|
for (unsigned int current_size = old_size; current_size < reaction_iterations; current_size++)
|
|
{
|
|
reaction_cache[pair].push_back(unordered_map<char,unsigned long long>());
|
|
}
|
|
}
|
|
|
|
unordered_map<char, unsigned long long> out_counts;
|
|
out_counts[reactions[pair]] = 1;
|
|
|
|
string left_pair = pair.substr(0,1) + reactions[pair];
|
|
string right_pair = reactions[pair] + pair.substr(1,1);
|
|
|
|
unordered_map<char, unsigned long long> left_counts = get_count_after_reaction(reactions, left_pair, reaction_iterations-1);
|
|
unordered_map<char, unsigned long long> right_counts = get_count_after_reaction(reactions, right_pair, reaction_iterations-1);
|
|
|
|
for (auto &it : left_counts)
|
|
{
|
|
if (!out_counts.contains(it.first))
|
|
{
|
|
out_counts[it.first] = 0;
|
|
}
|
|
|
|
out_counts[it.first] += it.second;
|
|
}
|
|
|
|
for (auto &it : right_counts)
|
|
{
|
|
if (!out_counts.contains(it.first))
|
|
{
|
|
out_counts[it.first] = 0;
|
|
}
|
|
|
|
out_counts[it.first] += it.second;
|
|
}
|
|
|
|
reaction_cache[pair][reaction_iterations-1] = out_counts;
|
|
|
|
return out_counts;
|
|
} |