递归算法以查找非图形行中的所有可能解法

时间:2017-11-07 13:19:10

标签: algorithm recursion

我试图以一种强力的方式编写一个简单的非图形解算器,但我仍然坚持一个相对容易的任务。假设我有一行长度为10的线索[2,3]

所以解决方案是:

$$-$$$----
$$--$$$---
$$---$$$--
$$----$$$-
$$-----$$$
-$$----$$$
--$$---$$$
---$$--$$$
----$$-$$$
-$$---$$$-
--$$-$$$--

我想找到一行的所有可能的解决方案 我知道我必须分别考虑每个块,并且每个块将有一个可用空间n-(剩余块长度之和+剩余块数)但我不知道如何从这里进展

2 个答案:

答案 0 :(得分:4)

嗯,这个问题已经有了一个很好的答案,所以再想想这个作为python实力的广告。

def place(blocks,total):
    if not blocks: return ["-"*total]
    if blocks[0]>total: return []

    starts = total-blocks[0] #starts = 2 means possible starting indexes are [0,1,2]
    if len(blocks)==1: #this is special case
        return [("-"*i+"$"*blocks[0]+"-"*(starts-i)) for i in range(starts+1)]

    ans = []
    for i in range(total-blocks[0]): #append current solutions
        for sol in place(blocks[1:],starts-i-1): #with all possible other solutiona
            ans.append("-"*i+"$"*blocks[0]+"-"+sol)

    return ans

测试它:

for i in place([2,3,2],12):
    print(i)

产生的输出如下:

$$-$$$-$$---
$$-$$$--$$--
$$-$$$---$$-
$$-$$$----$$
$$--$$$-$$--
$$--$$$--$$-
$$--$$$---$$
$$---$$$-$$-
$$---$$$--$$
$$----$$$-$$
-$$-$$$-$$--
-$$-$$$--$$-
-$$-$$$---$$
-$$--$$$-$$-
-$$--$$$--$$
-$$---$$$-$$
--$$-$$$-$$-
--$$-$$$--$$
--$$--$$$-$$
---$$-$$$-$$

答案 1 :(得分:2)

这就是我得到的:

#include <iostream>
#include <vector>
#include <string>

using namespace std;

typedef std::vector<bool> tRow;

void printRow(tRow row){
    for (bool i : row){
        std::cout << ((i) ? '$' : '-');
    }
    std::cout << std::endl;
}

int requiredCells(const std::vector<int> nums){
    int sum = 0;
    for (int i : nums){
        sum += (i + 1); // The number + the at-least-one-cell gap at is right
    }
    return (sum == 0) ? 0 : sum - 1; // The right-most number don't need any gap
}

bool appendRow(tRow init, const std::vector<int> pendingNums, unsigned int rowSize, std::vector<tRow> &comb){
    if (pendingNums.size() <= 0){
        comb.push_back(init);
        return false;
    }
    int cellsRequired = requiredCells(pendingNums);
    if (cellsRequired > rowSize){
        return false;   // There are no combinations
    }
    tRow prefix;
    int gapSize = 0;
    std::vector<int> pNumsAux = pendingNums;
    pNumsAux.erase(pNumsAux.begin());
    unsigned int space = rowSize;
    while ((gapSize + cellsRequired) <= rowSize){
        space = rowSize;
        space -= gapSize;
        prefix.clear();
        prefix = init;
        for (int i = 0; i < gapSize; ++i){
            prefix.push_back(false);
        }
        for (int i = 0; i < pendingNums[0]; ++i){
            prefix.push_back(true);
            space--;
        }
        if (space > 0){
            prefix.push_back(false);
            space--;
        }
        appendRow(prefix, pNumsAux, space, comb);
        ++gapSize;
    }
    return true;
}

std::vector<tRow> getCombinations(const std::vector<int> row, unsigned int rowSize) {
    std::vector<tRow> comb;
    tRow init;
    appendRow(init, row, rowSize, comb);
    return comb;
}

int main(){
    std::vector<int> row = { 2, 3 };

    auto ret = getCombinations(row, 10);

    for (tRow r : ret){
        while (r.size() < 10)
            r.push_back(false);

        printRow(r);
    }

    return 0;

}

我的输出是:

  

$$ - $$$ ----

     

$$ - $$$ ---

     

$$ --- $$$ -

     

$$ ---- $$$ -

     

$$ ----- $$$

     

- $$ - $$$ ----

     

- $$ - $$$ -

     

- $$ --- $$$ -

     

- $$ ---- $$$ -

     

- $$ - $$$ -

     

- $$ - $$$ -

     

- $$ --- $$$

     

--- $$ - $$$ -

     

--- $$ - $$$

     

---- $$ - $$$

当然,必须绝对可以改进。

注意:我没有比已编写的案例更多地测试它

希望它适合你