0

我一直在尝试解决涉及组合学和动态编程的编程挑战。

点击这里阅读问题

好消息是我已经解决了它,但是对于某些输入,程序会抛出错误的答案。

该程序将两个数字作为输入。让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 并转换为整数。

例如

  1. argv 1 = 20

  2. 20*2 = 40

  3. 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 编写的函数并排比较某些输入时,输出是相同的,而对于其他一些(如上所示)输出是不同的。

任何帮助将不胜感激。

非常感谢!

4

1 回答 1

0

我已经解决了这个问题,答案很简单,对条件进行了细微的修改。

基本上,我正在生成一组额外的可能组合,为了摆脱它,我需要扩展我的初始条件。

基本上,紧随其后:

vector<bool> vAux(iK-i);

我需要将以下所有说明包含在以下条件中:

if(iOffset <= iK-i)

这解决了我的问题。

谢谢大家看我的问题!

于 2012-11-20T18:18:03.820 回答