- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
给定 N 个盒子。我怎样才能找到按照给定顺序用它们制作的最高塔? (给定的顺序意味着第一个盒子必须在塔的底部,依此类推)。 所有盒子都必须用于制作有效的塔。
可以在任何轴上旋转盒子,使其 6 个面中的任何一个与地面平行,但是该面的周长必须完全限制在其下方盒子的上表面周长内.在第一个盒子的情况下,可以选择任何面,因为地面足够大。
为了解决这个问题,我尝试了以下方法:
- 首先,代码为每个矩形生成旋转(只是尺寸的排列)
- 其次为每个盒子和每个可能的旋转构造一个动态规划解决方案
- 最后搜索最高的塔(在 dp 表中)
但是我的算法在未知的测试用例中给出了错误的答案。有什么问题吗?动态规划是解决这个问题的最佳方法?
这是我的代码:
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <cstring>
struct rectangle{
int coords[3];
rectangle(){ coords[0] = coords[1] = coords[2] = 0; }
rectangle(int a, int b, int c){coords[0] = a; coords[1] = b; coords[2] = c; }
};
bool canStack(rectangle ¤t_rectangle, rectangle &last_rectangle){
for (int i = 0; i < 2; ++i)
if(current_rectangle.coords[i] > last_rectangle.coords[i])
return false;
return true;
}
//six is the number of rotations for each rectangle
int dp(std::vector< std::vector<rectangle> > &v){
int memoization[6][v.size()];
memset(memoization, -1, sizeof(memoization));
//all rotations of the first rectangle can be used
for (int i = 0; i < 6; ++i) {
memoization[i][0] = v[0][i].coords[2];
}
//for each rectangle
for (int i = 1; i < v.size(); ++i) {
//for each possible permutation of the current rectangle
for (int j = 0; j < 6; ++j) {
//for each permutation of the previous rectangle
for (int k = 0; k < 6; ++k) {
rectangle &prev = v[i - 1][k];
rectangle &curr = v[i][j];
//is possible to put the current rectangle with the previous rectangle ?
if( canStack(curr, prev) ) {
memoization[j][i] = std::max(memoization[j][i], curr.coords[2] + memoization[k][i-1]);
}
}
}
}
//what is the best solution ?
int ret = -1;
for (int i = 0; i < 6; ++i) {
ret = std::max(memoization[i][v.size()-1], ret);
}
return ret;
}
int main ( void ) {
int n;
scanf("%d", &n);
std::vector< std::vector<rectangle> > v(n);
for (int i = 0; i < n; ++i) {
rectangle r;
scanf("%d %d %d", &r.coords[0], &r.coords[1], &r.coords[2]);
//generate all rotations with the given rectangle (all combinations of the coordinates)
for (int j = 0; j < 3; ++j)
for (int k = 0; k < 3; ++k)
if(j != k) //micro optimization disease
for (int l = 0; l < 3; ++l)
if(l != j && l != k)
v[i].push_back( rectangle(r.coords[j], r.coords[k], r.coords[l]) );
}
printf("%d\n", dp(v));
}
输入描述
A test case starts with an integer N, representing the number of boxes (1 ≤ N ≤ 10^5). Following there will be N rows, each containing three integers, A, B and C, representing the dimensions of the boxes (1 ≤ A, B, C ≤ 10^4).
输出描述
Print one row containing one integer, representing the maximum height of the stack if it’s possible to pile all the N boxes, or -1 otherwise.
示例输入
25 2 21 3 4
示例输出
6
给定输入和输出的示例图像。
最佳答案
通常,您会得到导致您失败的测试用例。否则,发现问题要困难得多。
你总是可以从不同的角度接近它!我将省略那些很容易复制的无聊部分。
struct Box { unsigned int dim[3]; };
Box
将存储每个...框的尺寸。当需要读取维度时,需要对其进行排序,以便 dim[0] >= dim[1] >= dim[2]
。
想法是循环并在每次迭代时读取下一个框。然后它将新盒子的第二大尺寸与上一个盒子的第二大尺寸进行比较,并且与第三大尺寸相同。如果在任何一种情况下,较新的框较大,它都会调整较旧的框以比较第一大和第三大尺寸。如果那也失败了,那么第一和第二大。这样,它总是更喜欢使用更大的维度作为垂直维度。
如果它必须旋转一个框,它会转到下一个框并检查是否也不需要在那里调整旋转。它一直持续到没有更多的盒子或者不需要旋转下一个盒子为止。如果在任何时候,一个盒子的所有三个旋转都未能使其足够大,它就会停止,因为没有解决方案。
一旦所有框都就位,它只是总结每个框的垂直尺寸。
int main()
{
unsigned int size; //num boxes
std::cin >> size;
std::vector<Box> boxes(size); //all boxes
std::vector<unsigned char> pos(size, 0); //index of vertical dimension
//gets the index of dimension that isn't vertical
//largest indicates if it should pick the larger or smaller one
auto get = [](unsigned char x, bool largest) { if (largest) return x == 0 ? 1 : 0; return x == 2 ? 1 : 2; };
//check will compare the dimensions of two boxes and return true if the smaller one is under the larger one
auto check = [&boxes, &pos, &get](unsigned int x, bool largest) { return boxes[x - 1].dim[get(pos[x - 1], largest)] < boxes[x].dim[get(pos[x], largest)]; };
unsigned int x = 0, y; //indexing variables
unsigned char change; //detects box rotation change
bool fail = false; //if it cannot be solved
for (x = 0; x < size && !fail; ++x)
{
//read in the next three dimensions
//make sure dim[0] >= dim[1] >= dim[2]
//simple enough to write
//mine was too ugly and I didn't want to be embarrassed
y = x;
while (y && !fail) //when y == 0, no more boxes to check
{
change = pos[y - 1];
while (check(y, true) || check(y, false)) //while invalid rotation
{
if (++pos[y - 1] == 3) //rotate, when pos == 3, no solution
{
fail = true;
break;
}
}
if (change != pos[y - 1]) //if rotated box
--y;
else
break;
}
}
if (fail)
{
std::cout << -1;
}
else
{
unsigned long long max = 0;
for (x = 0; x < size; ++x)
max += boxes[x].dim[pos[x]];
std::cout << max;
}
return 0;
}
它适用于我编写的测试用例,但鉴于我不知道是什么原因导致您的失败,我无法告诉您我的有何不同(假设它也不会失败您的测试条件) .
关于c++ - 按给定顺序堆叠箱子的最高塔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35690398/
这是我正在做的作业。我创建了 2 个类来玩汉诺塔。第一个基本上是运行实际游戏类的运行者。 import java.util.Scanner; class TowersRunner { publ
这是我为汉诺塔问题编写的 Python 代码,其中塔必须从左桩转移到中间桩,使用右桩作为备用: def hanoi(n, origin = "1", destination = "2", spare
我正在使用 jQuery 标签!库创建用户“技能”输入表单。我认为这将是一个非常快速和简单的设置,就像大多数 jQuery 库一样,但是我在这个方面遇到了很多麻烦。我尝试按照下面示例中的源代码进行操作
我如何(如果可能)使用 C++11 可变参数编程来定义一系列 vector是在一个函数体内,(或者换句话说,一系列 N 维数组,递减 N 直到 0),就像下面的变量一样? vector>> v; ve
我编写了一个 Ansible playbook,它需要运行它的作业编号作为其参数之一,以便我将对该作业的引用添加到我维护的数据库中。如何获取 Tower 模板以将其传递给剧本? 这是我当前的解决方案,
默认情况下,android 会存储最后 200 个 wifi 连接和 50 个单元位置详细信息。 我使用 WifiManager 中的 getConfiguredNetworks() 获得了 wifi
如何(如果可能)使用 c++11 可变参数编程来定义一系列 vector 's 在函数体中,(或者换句话说,N 维数组的序列,N 's 递减直到 0),就像下面的变量? vector>> v; vec
我们正在 Tensorflow 上运行多 GPU 作业,并评估从基于队列的模型(使用 string_input_producer 接口(interface))到新的 Tensorflow 数据集 AP
我有一个由另一个进程启动的 Ansible 作业。现在我需要检查 Ansible Tower 中当前正在运行的作业的状态。 我可以使用 REST API 使用 /jobs/{id} 跟踪状态是否正在运
我正在使用一个非常棒的插件,名为 jQuery Tagit在我当前项目的开发中。 一切都进行得很顺利(令人怀疑),直到我尝试添加自己的一小部分 jQuery。我的目标是让最终用户可以选择使用按钮添加标
我是一名优秀的程序员,十分优秀!