-
Notifications
You must be signed in to change notification settings - Fork 0
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
338 additions
and
1 deletion.
There are no files selected for viewing
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,117 @@ | ||
#include <iostream> | ||
#include <vector> | ||
#include <list> | ||
#include <set> | ||
#include <algorithm> | ||
|
||
using namespace std; | ||
|
||
using State = vector<int>; | ||
using Path = list<State>; | ||
|
||
class Pouring | ||
{ | ||
public: | ||
Pouring(vector<int> v): _capacities{v} {} | ||
|
||
State Empty(int idx, State s) | ||
{ | ||
s[idx] = 0; | ||
return s; | ||
} | ||
|
||
State Fill(int idx, State s) | ||
{ | ||
s[idx] = _capacities[idx]; | ||
return s; | ||
} | ||
|
||
State Pour(int src, int tgt, State s) | ||
{ | ||
int diff = _capacities[tgt] - s[tgt]; | ||
if (s[src] > diff) { | ||
s[tgt] = _capacities[tgt]; | ||
s[src] = s[src] - diff; | ||
} else { | ||
s[tgt] = s[tgt] + s[src]; | ||
s[src] = 0; | ||
} | ||
return s; | ||
} | ||
|
||
set<State> extend(State s) { | ||
set<State> S; | ||
for (int i=0; i<_capacities.size(); ++i) { | ||
S.insert(Empty(i, s)); | ||
S.insert(Fill(i, s)); | ||
for (int j=0; j<_capacities.size(); ++j) { | ||
if (i!=j) { | ||
S.insert(Pour(i, j, s)); | ||
} | ||
} | ||
} | ||
return S; | ||
} | ||
|
||
bool found(State s, int goal) { | ||
return any_of(s.cbegin(), s.cend(), [goal](int x) { return x==goal;}); | ||
} | ||
|
||
void solve(int goal, int steps) { | ||
Path initialPath; | ||
initialPath.push_back(State(_capacities.size())); | ||
_paths.insert(initialPath); | ||
|
||
while (steps > 0) { | ||
set<Path> newPaths; | ||
|
||
for (const auto & p: _paths) { | ||
_explored.insert(p.back()); // p.back() is a State p is a list of States | ||
auto nextStates = extend(p.back()); | ||
for (const auto &s : nextStates) { | ||
if (found(s, goal)) { | ||
auto np = p; | ||
np.push_back(s); | ||
_solutions.insert(np); | ||
} else { | ||
if (_explored.find(s) == _explored.cend()) { | ||
auto np = p; | ||
np.push_back(s); | ||
newPaths.insert(np); | ||
} | ||
} | ||
} | ||
} | ||
_paths = newPaths; | ||
--steps; | ||
} | ||
} | ||
|
||
void show_solutions() { | ||
for (const auto& p: _solutions) { | ||
for (const auto& s: p) { | ||
cout << "("; | ||
for (const auto& x: s) { | ||
cout << x << ", "; | ||
} | ||
cout << ") -> "; | ||
} | ||
cout << "\n"; | ||
} | ||
} | ||
|
||
|
||
private: | ||
vector<int> _capacities; | ||
set<Path> _solutions; | ||
set<Path> _paths; | ||
set<State> _explored; | ||
}; | ||
|
||
int main() | ||
{ | ||
vector<int> jugs{3, 4, 7}; | ||
Pouring problem{jugs}; | ||
problem.solve(5, 6); | ||
problem.show_solutions(); | ||
} |
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,129 @@ | ||
#include <iostream> | ||
#include <vector> | ||
#include <algorithm> | ||
#include <set> | ||
#include <list> | ||
#include <iterator> | ||
#include <string> | ||
#include <sstream> | ||
using namespace std; | ||
using State = vector<int>; | ||
class Pouring | ||
{ | ||
private: | ||
vector<int> _capacities; // {3, 5} | ||
set<State> _explored; | ||
set<list<State>> _paths; | ||
set<list<State>> _solutions; | ||
|
||
public: | ||
Pouring(vector<int> cp): _capacities{cp} { } | ||
State Empty(State s, int jug_no) | ||
{ | ||
s[jug_no] = 0; | ||
return s; | ||
} | ||
State Fill(State s, int jug_no) | ||
{ | ||
s[jug_no] = _capacities[jug_no]; | ||
return s; | ||
} | ||
State Pour(State s, int from, int to) | ||
{ | ||
State t = s; | ||
int diff = _capacities[to]-s[to]; | ||
if (diff < s[from]) { | ||
t[to] = _capacities[to]; | ||
t[from] = s[from]-diff; | ||
} else { | ||
t[from] = 0; | ||
t[to] = s[to] + s[from]; | ||
} | ||
return t; | ||
} | ||
set<State> extend(State s) | ||
{ | ||
set<State> SS; | ||
for (int i=0; i<_capacities.size(); ++i) { | ||
SS.insert(Empty(s, i)); | ||
SS.insert(Fill(s, i)); | ||
for (int j=0; j<_capacities.size(); ++j) { | ||
if (i!=j) | ||
SS.insert(Pour(s, i, j)); | ||
} | ||
} | ||
return SS; | ||
} | ||
|
||
void show_state(State s) | ||
{ | ||
for (auto i : s) | ||
cout << i << ", " ; | ||
cout << "->"; | ||
} | ||
bool found(State s, int target) | ||
{ | ||
for (auto t : s) { | ||
if (t==target) return true; | ||
} | ||
return false; | ||
// return any_of(s.cbegin(), s.cend(), [=](int v){ return target==v;}); | ||
} | ||
void solve(int target, int steps) | ||
{ | ||
list<State> initialPath; | ||
initialPath.push_back(State(_capacities.size())); | ||
_paths.insert(initialPath); | ||
|
||
while (steps > 0) { | ||
set<list<State>> newPaths; | ||
set<list<State>> oldPaths; | ||
|
||
for (auto p : _paths) { | ||
_explored.insert(p.back()); | ||
auto nextStates = extend(p.back()); | ||
for (auto s : nextStates) { | ||
if (found(s, target)) { | ||
auto np = p; | ||
np.push_back(s); | ||
_solutions.insert(np); | ||
} else { | ||
auto search = _explored.find(s); | ||
if (search == _explored.cend()) { | ||
auto np = p; | ||
np.push_back(s); | ||
newPaths.insert(np); | ||
} | ||
} | ||
} | ||
oldPaths.insert(p); | ||
} | ||
|
||
for (auto p : oldPaths) { | ||
_paths.erase(p); | ||
} | ||
for (auto p : newPaths) { | ||
_paths.insert(p); | ||
} | ||
--steps; | ||
} | ||
|
||
} | ||
void show_solutions() | ||
{ | ||
for (auto path : _solutions) { | ||
for (auto state : path) { | ||
show_state(state); | ||
} | ||
cout << "\n"; | ||
} | ||
} | ||
}; | ||
|
||
int main() | ||
{ | ||
vector<int> jugs = {3, 5}; | ||
Pouring problem(jugs); | ||
problem.solve(4, 6); | ||
problem.show_solutions(); | ||
} |
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,45 @@ | ||
#include <iostream> | ||
#include <vector> | ||
#include <map> | ||
#include <cmath> // pow | ||
#include <algorithm> // sort & lower_bound & upper_bound | ||
#include <string> // to_string | ||
using namespace std; | ||
using ll = long long; | ||
|
||
int main(){ | ||
int n, k; | ||
while( cin >> n >> k ){ | ||
vector<ll> a(n,0); | ||
for(int i = 0; i < n; ++i){ | ||
cin >> a[i]; | ||
} | ||
|
||
map<int, vector<int>> rem; | ||
for(int i = 1; i <= 9; ++i){ | ||
for(int j = 0; j < n; ++j){ | ||
ll tmp = a[j] * (ll)pow(10, i) % k; | ||
rem[i].emplace_back(tmp); | ||
} | ||
sort(rem[i].begin(), rem[i].end()); | ||
} | ||
|
||
int ans = 0; | ||
for(auto& a_i: a){ | ||
int len = to_string(a_i).size(); | ||
int target = k - (a_i % k); | ||
// Case1: a_i 不是k的倍數 | ||
if(target != k){ | ||
ans += upper_bound(rem[len].begin(), rem[len].end(), target) - lower_bound(rem[len].begin(), rem[len].end(), target); | ||
// 檢查有沒有用到自己 | ||
if((a_i * (ll)pow(10, len) + a_i ) % k == 0) ans--; | ||
// Case2: a_i 是k的倍數 | ||
}else{ | ||
ans += upper_bound(rem[len].begin(), rem[len].end(), 0) - lower_bound(rem[len].begin(), rem[len].end(), 0); | ||
if((a_i * (ll)pow(10, len) + a_i ) % k == 0) ans--; | ||
} | ||
} | ||
cout << ans << endl; | ||
} | ||
|
||
} |
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,43 @@ | ||
#include <iostream> | ||
#include <map> | ||
#include <vector> | ||
#include <string> | ||
#include <algorithm> | ||
using namespace std; | ||
|
||
map<int, map<char, vector<string>>> bucket; | ||
|
||
int countnum(string& s){ | ||
return count_if(s.begin(), s.end(), [](char c){ return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u'; }); | ||
} | ||
|
||
char countlast(string& s){ | ||
return *(find_if(s.rbegin(), s.rend(), [](char c){ return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u'; })); | ||
} | ||
|
||
int main(){ | ||
int n; cin >> n; | ||
while(n--){ | ||
string s; cin >> s; | ||
bucket[countnum(s)][countlast(s)].emplace_back(s); | ||
} | ||
|
||
int comp = 0, uncomp = 0; | ||
for(auto [x, y]: bucket){ | ||
for(auto [w, v]: y){ | ||
comp += v.size()/2; | ||
} | ||
int tmp = 0; | ||
for(auto [w, v]: y){ | ||
tmp += v.size()%2; | ||
} | ||
uncomp += tmp/2; | ||
} | ||
|
||
int ans = min(comp, uncomp); | ||
int diff = comp - uncomp; | ||
ans += ( diff >= 2 )? diff/2: 0; | ||
cout << ans << 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