我一直在尝试解决涉及组合学和动态编程的编程挑战。
好消息是我已经解决了它,但是对于某些输入,程序会抛出错误的答案。
该程序将两个数字作为输入。让w = argv[1]
,h = argv[2]
我将以伪数学方式编写它以便于表示
例如下面的“公式”表示我的程序接受两个参数:w和h,输出为x
T(w,h) = x
我将用 表示理论结果,用 表示T(w,h)
我的程序的结果R(w, h)
。我 100% 确定这T(w, h)
将永远是正确的答案。
我们走吧:
T(10, 10) = 2
R(10, 10) = 2
T(11, 10) = 2
R(11, 10) = 288
**结果不同**
T(12, 10) = 4
R(12, 10) = 4
T(13, 10) = 4
R(13, 10) = 4
T(14, 10) = 66
R(14, 10) = 66
T(15, 10) = 290
R(15, 10) = 290
T(20, 10) = 9594
R(20, 10) = 98826
结果不同
T(25, 10) = 419854
R(25, 10) = 419854
T(30, 10) = 94082988
R(30, 10) = 94082988
T(35, 10) = 5578404294
R(35, 10) = 1283436998
从这一点开始,结果总是不同的
T(36, 10) = 19730715436
R(36, 10) = 18446744071965430572
数据类型溢出?
T(37, 10) = 19730715436
R(37, 10) = 18446744071965430572
T(38, 10) = 73368404198
R(38, 10) = 393345822
这个结果比上一个小,应该比上一个大。
T(39, 10) = 287780277370
R(39, 10) = 17468538
T(40, 10) = 287780277370
R(40, 10) = 17468538
T(41, 10) = 1095232487336
R(41, 10) = 15826856
T(42, 10) = 4013757692218
R(42, 10) = 18446744071672822074
再次上升。花费大量时间进行计算
我想这对于黑盒测试来说已经足够了,现在让我们看一下算法和实际代码。
第一个参数乘以 2,除以 3 并转换为整数。
例如
argv 1 = 20
20*2 = 40
40/3 = 13整数除法
该值被传递给给我带来问题的函数。
让它iNormalizedWidth
成为那个值。
如果iNormalizedWidth
是奇数,程序会一直给我一个错误的答案。只给我以下数字的错误答案:
11、20、25、29、35-48。
(48 是我的程序将处理的最大值)。
这是我写的函数:
typedef long long int int64;
#define BLOCK_A = 2;
#define BLOCK_B = 3;
/* main function, more macros, prototypes of other functions and
irrelevant information for the scope of my question */
vector< vector<int64> > iTileBricks(int iWidth) {
int iK, i, j, iMaxIterations, iEvenWidth, iOffset;
vector<int64> viBrickRange;
vector< vector<int64> > viBrickWall;
vector< vector<int64> > viResult;
iEvenWidth = iWidth % 2;
iK = (int)(iWidth/2); // The amount of all possible combinations that follow the pattern nCr(iN-i,2i)
iMaxIterations = iK/3 + 1; // By dividing all the possible combinations by 3, I am finding out how the maximum amount of iterations
for(i = 0; i < iMaxIterations; i++) {
iOffset = 2*i + iEvenWidth;
vector<bool> vAux(iK-i); // Creating a iK - i long vector. Test Case:
// Let dOriginalPanelWidth = 48
// iPanelWidth = 32
// iK = iPanelWidth/2 = 16
// iMaxIterations = iK/3 ~= 5
// iK - i = 16 - i Where 1 <= i <= 5
// For the first iteration of i the value of vAux will be:
if(iOffset <= iK-i) {
fill(vAux.begin() + iOffset, vAux.end(), true); // For the first iteration of i the value of vAux will be:
}
// vAux = [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
do { // In this block of code I'm generating all the possible layouts of bricks that can build
for(j = 0; j < iK-i; j++) { // a wall of 48" (or any value of width where 3 <= width <= 48 and (width % 1/2) == 0).
if(vAux[j] == false) {
viBrickRange.push_back(j); // Generating n-tuples with all possible combinations
}
}
viBrickWall.push_back(viBrickRange);
viBrickRange.clear();
} while(next_permutation(vAux.begin(), vAux.end()));
for(unsigned int a=0; a < viBrickWall.size(); a++) {
vector<int64> viTmp(iK-i);
fill(viTmp.begin(), viTmp.end(), BLOCK_A);
for(unsigned int b = 0; b < viBrickWall[a].size(); b++) {
viTmp[viBrickWall[a][b]] = BLOCK_B;
}
viResult.push_back(viTmp);
viTmp.clear();
}
viBrickWall.clear();
vAux.clear();
}
return viResult;
}
我找到了一个用python编写的程序,后一个函数只不过是从python函数到C++的一个端口。如果有帮助,仅供参考:
def all_single_rows(width):
result = []
n = width / 2
width_parity = width % 2
for i in range(n/3 + 1):
for bits in combinations(range(n-i), 2*i + width_parity):
s = [2] * (n-i)
for bit in bits:
s[bit] = 3
result.append(s)
return result
这是一个相当大的功能(和问题),但我整天都在尝试调试它,但我一直无法提出解决方案。
生成最终值的计算更多,但这是导致其他函数失败的函数。
我想知道关于为什么某些输入的任何理论,答案飙升,然后又回来了。
当我将我的函数与用 python 编写的函数并排比较某些输入时,输出是相同的,而对于其他一些(如上所示)输出是不同的。
任何帮助将不胜感激。
非常感谢!