如何有效地检查10个变量是否不同

时间:2014-07-10 18:49:23

标签: c++ conditional-statements

我正在尝试使用c ++解决以下数学问题:

(Each letter represents an individual digit)

  WHITE
+ WATER
-------
 PICNIC

到目前为止,我有这个代码来解决难题:

#include <iostream>

using namespace std;

int main(int argc, char **argv) {
  for (int w = 5; w < 10; w++) {
    for (int h = 0; h < 10; h++) {
      for (int i = 0; i < 10; i++) {
        for (int t = 0; t < 10; t++) {
          for (int e = 0; e < 10; e++) {
            for (int a = 0; a < 10; a++) {
              for (int r = 0; r < 10; r++) {
                for (int p = 0; p < 10; p++) {
                  for (int c = 0; c < 10; c++) {
                    for (int n = 0; n < 10; n++) {
                      // I need to check if all the digits are different here
                      if (10000 * w + 1000 * h + 100 * i + 10 * t + e + 10000 * w + 1000 * a + 100 * t + 10 * e + r == 100000 * p + 10000 * i + 1000 * c + 100 * n + 10 * i + c) {
                          cout << "W: " << w << endl;
                          cout << "H: " << h << endl;
                          cout << "I: " << i << endl;
                          cout << "T: " << t << endl;
                          cout << "E: " << e << endl;
                          cout << "A: " << a << endl;
                          cout << "R: " << r << endl;
                          cout << "P: " << p << endl;
                          cout << "C: " << c << endl;
                          cout << "N: " << n << endl;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

是否有一些快速测试可以运行以检查所有数字是否都不同(有10个不同的字母,所以一个必须是0,一个必须是1,等等)

修改

我尝试添加它们并检查是否等于45.我可以编写另一个程序/方法,在嵌套循环完成后清除结果,但有没有更好的方法?

3 个答案:

答案 0 :(得分:7)

您可以使用以下

return ((1 << W)
     | (1 << H)
     | (1 << I)
     | (1 << T)
     | (1 << E)
     | (1 << A)
     | (1 << R)
     | (1 << P)
     | (1 << C)
     | (1 << N))
     == 0x03FF;

答案 1 :(得分:2)

w中除std::vector之外的所有数字放在std::vector<int> letters(9); for(int w=5;w!=10;++w) { for(int i=0;i!=9;++i) letters[i] = (i<w) ? i : i+1; do { int h = letters[0]; int i = letters[1]; //etc } while(std::next_permutation(letters.begin(), letters.end())); } 中,并使用std :: next_permutation迭代它们的所有排列,为你的字母分配它们:

std::next_permutation

然后,您将通过构造对字母进行有效的数字分配,并且不需要检查它们是否有所不同,将性能提高了一千倍(具体取决于多少) std::vector<int> letters(10); letters[0] = 5; for(int i=0;i!=9;++i) letters[i+1] = (i<5) ? i : i+1; do { int w = letters[0]; int h = letters[1]; int i = letters[2]; //etc } while(std::next_permutation(letters.begin(), letters.end())); )的平均成本。

修改

实际上,考虑一下,我意识到你可以用

更容易地做到这一点
next_permutation

因为letters[0]按字典顺序迭代排列,所以{{1}}不能小于5。

答案 2 :(得分:1)

免责声明:Jarod42的回答是正确的。

我发布代码的唯一原因是因为我很惊讶地发现W&lt; W&lt; W&lt; 5.此外,此代码运行时间不到1秒。

#include <iostream>
#include <numeric>
#include <algorithm>
#include <array>

int white(const std::array<int, 10>& x)
{
    // W H I T E A R P C N
    return 10000 * x[0] + 1000 * x[1] + 100 * x[2] + 10 * x[3] + 1 * x[4];
}

int water(const std::array<int, 10>& x)
{
    // W H I T E A R P C N
    return 10000 * x[0] + 1000 * x[5] + 100 * x[3] + 10 * x[4] + 1 * x[6];
}

int picnic(const std::array<int, 10>& x)
{
    // W H I T E A R P C N
    return 100000 * x[7] + 10010 * x[2] + 1001 * x[8] + 100 * x[9];
}

int main(int, char *[])
{
    std::array<int, 10> x;

    std::iota(x.begin(), x.end(), 0);

    do {
        if (white(x) + water(x) == picnic(x)) {
            std::cout << white(x) << " + " << water(x) << " = " << picnic(x) << "\n";
        }
    } while (std::next_permutation(x.begin(), x.end()));

    return 0;
}

注意:我已准备好进行投票...我只需要休息15分钟。