132 lines
3.9 KiB
C++
132 lines
3.9 KiB
C++
#include <iostream>
|
|
#include <list>
|
|
|
|
using namespace std;
|
|
|
|
struct Node {
|
|
Node *left;
|
|
Node *right;
|
|
int64_t height;
|
|
};
|
|
|
|
|
|
void createNewNode(Node &parent, list<Node> &freeNodesLeft, list<Node> &freeNodesRight, int64_t new_height, bool direction) {
|
|
// Found a node that will not increase total height. Using
|
|
Node newNode;
|
|
newNode.height = new_height;
|
|
|
|
freeNodesLeft.push_back(newNode);
|
|
freeNodesRight.push_back(newNode);
|
|
|
|
if(!direction) {
|
|
parent.left = &newNode;
|
|
} else {
|
|
parent.right = &newNode;
|
|
}
|
|
}
|
|
|
|
|
|
int64_t calculateHeight(int64_t N, int64_t leftHeight, int64_t rightHeight) {
|
|
if (N == 1) {
|
|
return 0;
|
|
}
|
|
|
|
int64_t totalHeight = 0;
|
|
Node parentNode;
|
|
parentNode.height = 0;
|
|
|
|
list<Node> freeNodesLeft;
|
|
list<Node> freeNodesRight;
|
|
|
|
freeNodesLeft.push_back(parentNode);
|
|
freeNodesRight.push_back(parentNode);
|
|
|
|
int64_t longestRoad = max(leftHeight, rightHeight);
|
|
|
|
// Calculate all houses after first one
|
|
for (int64_t i = 1; i < N; i++) {
|
|
Node lowestNodeLeft;
|
|
lowestNodeLeft.height = longestRoad * N;
|
|
auto lowestNodeLeftIt = freeNodesLeft.end();
|
|
|
|
bool foundFreeSolution = false;
|
|
|
|
// Find lowest left node. Also check if using any of the existing nodes will not increase total height
|
|
for (auto it = freeNodesLeft.begin(); it != freeNodesLeft.end(); it++) {
|
|
Node node = *it;
|
|
int64_t new_height = node.height + leftHeight;
|
|
|
|
if (new_height <= totalHeight) {
|
|
// Found a node that will not increase total height. Using it
|
|
createNewNode(node, freeNodesLeft, freeNodesRight, new_height, 0);
|
|
freeNodesLeft.erase(it);
|
|
foundFreeSolution = true;
|
|
break;
|
|
}
|
|
|
|
if (new_height < lowestNodeLeft.height) {
|
|
lowestNodeLeft = node;
|
|
lowestNodeLeftIt = it;
|
|
}
|
|
}
|
|
|
|
if (foundFreeSolution) {
|
|
continue;
|
|
}
|
|
|
|
Node lowestNodeRight;
|
|
lowestNodeRight.height = longestRoad * N;
|
|
auto lowestNodeRightIt = freeNodesRight.end();
|
|
|
|
// Find lowest right node. Also check if using any of the existing nodes will not increase total height
|
|
for (auto it = freeNodesRight.begin(); it != freeNodesRight.end(); it++) {
|
|
Node node = *it;
|
|
int64_t new_height = node.height + rightHeight;
|
|
|
|
if (new_height <= totalHeight) {
|
|
// Found a node that will not increase total height. Using
|
|
createNewNode(node, freeNodesLeft, freeNodesRight, new_height, 1);
|
|
freeNodesRight.erase(it);
|
|
foundFreeSolution = true;
|
|
break;
|
|
}
|
|
|
|
if (new_height < lowestNodeRight.height) {
|
|
lowestNodeRight = node;
|
|
lowestNodeRightIt = it;
|
|
}
|
|
}
|
|
|
|
if (foundFreeSolution) {
|
|
continue;
|
|
}
|
|
|
|
int64_t newHeightLeft = lowestNodeLeft.height + leftHeight;
|
|
int64_t newHeightRight = lowestNodeRight.height + rightHeight;
|
|
if (newHeightLeft < newHeightRight) {
|
|
createNewNode(lowestNodeLeft, freeNodesLeft, freeNodesRight, newHeightLeft, 0);
|
|
freeNodesLeft.erase(lowestNodeLeftIt);
|
|
totalHeight = newHeightLeft;
|
|
} else {
|
|
createNewNode(lowestNodeRight, freeNodesLeft, freeNodesRight, newHeightRight, 1);
|
|
freeNodesRight.erase(lowestNodeRightIt);
|
|
totalHeight = newHeightRight;
|
|
}
|
|
//cout << "i=" << i << "; total_height=" << totalHeight << endl;
|
|
}
|
|
|
|
return totalHeight;
|
|
}
|
|
|
|
int main() {
|
|
int64_t T;
|
|
cin >> T;
|
|
|
|
int64_t N, A, B;
|
|
for (int i = 0; i < T; i++) {
|
|
cin >> N >> A >> B;
|
|
cout << calculateHeight(N, A, B) << endl;
|
|
}
|
|
return 0;
|
|
}
|