在一根奇怪的绳子上排列

Permutation on a strange string

本文关键字:排列 一根      更新时间:2023-10-16

有一个由10个字符组成的奇怪字符串,分别为"0"或"1"。我有n个筛选器字符串,每个字符串包含10个字符,分别为"0"或"1"。过滤器字符串中第i个位置的"1"意味着,如果我将此过滤器应用于奇怪字符串的第i个字符,奇怪字符串的第一个字符将反转:如果它是"0",它将变为"1",反之亦然,而过滤器字符串中的第i位置的"0"对奇怪字符串没有任何作用。我可以应用任意数量的过滤器。我可以选择任意数量的过滤器,并可以应用于奇怪的字符串。现在我想知道我可以应用所有过滤器的多少不同子集来转换这个奇怪的字符串,这样奇怪的字符串只包含1?我不能将这个问题推广到任何数量的字符串。有人能帮忙吗。
让我们有一些测试用例

输入奇怪的字符串:
11111111111
过滤器字符串总数
2
输入筛选字符串
0000000000
0000000000
输出为:4
解释:奇怪的字符串已经有了所有字符1,我有两个不同的身份过滤器。我可以应用过滤器的空子集,只应用第一个过滤器,只应用第二个过滤器,或者两者都应用。
输入奇怪的字符串:
0101010101
过滤器字符串总数
3
输入筛选字符串
1010101010
1010000000
0000101010
输出为:2
解释
:我可以应用第一个过滤器(并反转所有0),也可以按任何顺序应用第二个和第三个过滤器。

Brute force算法:

std::uint16_t apply_filters(std::uint16_t init,
                            const std::vector<std::uint16_t>& filters,
                            const std::vector<bool>& mask)
{
    auto res = init;
    for (std::size_t i = 0; i != filters.size(); ++i) {
        if (mask[i]) {
            res ^= filters[i];
        }
    }
    return res;
}
bool increase(std::vector<bool>& bs)
{
    for (std::size_t i = 0; i != bs.size(); ++i) {
        bs[i] = !bs[i];
        if (bs[i] == true) {
            return true;
        }
    }
    return false; // overflow
}

std::size_t count_filters_combination(std::uint16_t init,
                                      const std::vector<std::uint16_t>& filters)
{
    std::vector<bool> bs(filters.size());
    std::size_t count = 0;
    const std::uint16_t expected = 0b1111111111;
    do
    {
        if (expected == apply_filters(init, filters, bs)) {
            ++count;
        }
    } while (increase(bs));
    return count;
}

实时演示

我用python编写了我的解决方案。它应该很容易理解。我把它留给你翻译成C++。

def filterCombinations(original, filters):
    combinations = 1 if original == 0b1111111111 else 0
    for i in xrange(len(filters)):
        newvalue = original ^ filters[i]
        newfilters = filters[i+1:]
        combinations += filterCombinations(newvalue, newfilters)
    return combinations

使用3个过滤器,第一级递归如下所示:

filterCombinations(S, [F1, F2, F3])
--> X +
    filterCombinations(S^F1, [F2, F3]) +
    filterCombinations(S^F2, [F3]) +
    filterCombinations(S^F3, [])

其中如果S == 1111111111X为1,否则0为1。