正如“btilly”先生所说,我们应该从所有可能的盒子旋转中创建一个图表。
每个节点代表一个旋转的(或原始形状)框。
只有当第二个盒子可以堆在第一个盒子上时,节点之间的边才能存在。
那么,让我们介绍一个描述盒子形状的结构:
struct BoxSizes {
int length{};
int width{};
int height{};
int type{-1};
int num_of_box{};
BoxSizes(const BoxSizes&) = default;
BoxSizes(const std::vector<int>& box, int type, int num_of_box) : length(box[0]), width(box[1]), height(box[2]), type(type), num_of_box(num_of_box) {}
/*Some helpful methods*/
我们给出这样的盒子形状:
std::vector<std::vector<int>> box_sizes = {
{269, 152, 375},
{45, 8, 259},
{37, 113, 98},
{685, 40, 35}
};
让我们创建盒子的所有旋转:
std::vector<BoxSizes> all_rotated_box;
for (const auto& box_as_vector : box_sizes) {
/*Don't pay attention on type and count*/
const auto& box = BoxSizes(box_as_vector, type++, count);
count += 3;
all_rotated_box.emplace_back(box);
all_rotated_box.emplace_back(rotateRight(box));
all_rotated_box.emplace_back(rotateOnward(box));
}
/*Let's sort them!*/
std::sort(all_rotated_box.begin(), all_rotated_box.end());
那么,我们来介绍一个结构Node
struct Node {
int x, y, z;
int type;
Node() = default;
Node(int _x, int _y, int _z, int type) : x(_x), y(_y), z(_z), type(type) {}
bool operator==(Node a) {
return (x == a.x) && (y == a.y);
}
};
std::vector<Node> nodes;
/*From vector of boxes to vector of nodes*/
std::transform(all_rotated_box.begin(), all_rotated_box.end(), std::back_inserter(nodes),
[](const auto& box) { return Node(box.length, box.width, box.height, box.type); });
让我们创建一个图表:
std::vector<std::vector<int>> Graph(nodes.size(), std::vector<int>(nodes.size(), 0));
for (int i = 0; i < nodes.size(); i++) {
auto x = nodes[i].x;
auto y = nodes[i].y;
auto type = nodes[i].type;
for (int j = 0; j < nodes.size(); j++) {
auto x_ = nodes[j].x;
auto y_ = nodes[j].y;
auto type_ = nodes[j].type;
if(i == j) {
Graph[i][j] = nodes[i].z;
}
if(type == type_ || (x == x_ && y == y_))
continue;
if((x < x_ || x <= x_) && (y < y_ || y <= y_) ||
(x < y_ || x <= y_) && (y < x_ || y <= x_)) {
Graph[i][j] = std::abs( nodes[j].z);
}
}
}
所以,主循环是:
for(auto j = 0; j < nodes.size(); j++) {
std::deque<int> q;
q.push_back(j);
std::vector<int> heighest(nodes.size(), 0);
heighest[j] = Graph[j][j];
while (!q.empty()) {
std::vector<int> adjacent_nodes;
auto curr{q.front()};
q.pop_front();
for (int i = 0; i < Graph[0].size(); i++) {
if (Graph[curr][i] > 0 && i != curr) {
adjacent_nodes.push_back(i);
}
}
for (auto node : adjacent_nodes) {
heighest[node] = std::max(heighest[node], heighest[curr] + Graph[curr][node]);
q.push_back(node);
}
}
the_heighest = std::max(the_heighest, *std::max_element(heighest.begin(), heighest.end()));
}
您可以在这里查看https://github.com/Ayrtat/codeforces/blob/master/BoxRight.cpp