-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path2008 S4 - Twenty-four.cpp
129 lines (91 loc) · 3.57 KB
/
2008 S4 - Twenty-four.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
2008 S4 - Twenty-four
Difficulty: Medium
This problem is kinda simple. Since there's only 4 cards, you can essentially just brute force through every combination of operations
To do this, write a recursive function that selects 2 cards at a time and applies some operation to them (+, -, *, /)
Watch out for non zero remainder division and dividing by 0 in general
*/
#include <iostream>
#include <set>
int max = 0; //Maximum amount that can be created
std::multiset<int> hand; //Multset storing the hand, I tried with vectors but i suck so I just switched to multiset for easy insertion and deletion
//Solve function, takes in a hand and selects 2 cards to apply operations to
void solve(std::multiset<int> h){
//If all cards have been combined, check if it's greater than max
if (h.size() == 1){
if (*h.begin() > max && *h.begin() <= 24){
max = *h.begin();
}
}
else{
//For each card1
for (auto it = h.begin(); it != h.end(); it++){
auto itt2 = it;
itt2++;
//For each card2
for (auto it2 = itt2; it2 != h.end(); it2++){
int card1 = *it;
int card2 = *it2;
//Create a temporary multiset to apply changes to
std::multiset<int> temp = h;
//Erase the cards that are to be combined
//Remember to use .find() to ensure only a single element is erased and not several duplicates
temp.erase(temp.find(card1));
temp.erase(temp.find(card2));
//Addition
int addition = card1 + card2;
temp.insert(addition);
solve(temp);
temp.erase(temp.find(addition));
//Subtraction, remember it results in different values depending on the order so just do both
int subtraction1 = card1 - card2;
temp.insert(subtraction1);
solve(temp);
temp.erase(temp.find(subtraction1));
int subtraction2 = card2 - card1;
temp.insert(subtraction2);
solve(temp);
temp.erase(temp.find(subtraction2));
//Multiplication, order doesnt matter
int multiplication = card2 * card1;
temp.insert(multiplication);
solve(temp);
temp.erase(temp.find(multiplication));
//Division, order does matter so do both
//Ensure that the denominator is not 0 otherwise you get floating point error
//Remember that no remainder is allowed
if (card2 != 0 && card1 % card2 == 0){
int division1 = card1 / card2;
temp.insert(division1);
solve(temp);
temp.erase(temp.find(division1));
}
if (card1 != 0 && card2 % card1 == 0){
int division2 = card2 / card1;
temp.insert(division2);
solve(temp);
temp.erase(temp.find(division2));
}
}
}
}
}
int main(){
int N;
std::cin >> N;
//For each hand
for (int i = 0; i < N; i++){
//Get hand
for (int j = 0; j < 4; j++){
int card;
std::cin >> card;
hand.insert(card);
}
solve(hand); //Solve
std::cout << max << '\n';
//Reset for next hand
max = 0;
hand.clear();
}
return 0;
}