私のアプローチはこのようなものになります。これは、2 から 9 までの数字を含むマルチセットであるセット S を、場合によっては複数回使用する再帰アルゴリズムです。
try (N, S, digit) {
for d = digit, digit-1, ..., 2 {
if N is divisible by d then {
S' = S + {d};
if N/d is composed of all the digits in S', perhaps with
some 1's thrown in, then N/d is an answer;
try (N/d, S', d);
}
}
}
次に、元の番号について
try (originalN, empty-set, 9);
also check originalN to see if it has only 1 digits (11, 11111, etc.); if so, then it's also an answer
これでうまくいくと思いますが、いくつかの境界ケースを見逃している可能性があります。
4977 の場合、try(4977, empty, 9)
は 4977 が 9 で割り切れることを検出するため、 を呼び出しますtry(553, {9}, 9)
。内部のtry
結果 553 は 7 で割り切れ、553/7 = 79 です。その時点で S' = {7, 9} となり、アルゴリズムは 79 が数字 {7, 9} で構成されているかどうかをチェックし、成功します。ただし、アルゴリズムは引き続き実行されます。最終的には外側のに戻り、try
ある時点で を試しd = 7
、4977/7 = 711 になります。チェックを行うと、S' = {7} で、711 は 7 と 1 で構成されているため、これも答え。
編集:私は完全な C++ 関数を含めました:
#include <iostream>
#include <vector>
using namespace std;
struct digitMultiset {
int counts[10]; // note: the [0] and [1] elements are not used
};
static const digitMultiset empty = { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
bool hasDigits (const int n, digitMultiset& s) {
digitMultiset s2 = empty;
int temp = n;
int digit;
while (temp > 0) {
digit = temp % 10;
if (digit == 0) return false;
if (digit != 1) s2.counts[digit]++;
temp /= 10;
}
for (int d = 2; d < 10; d++)
if (s2.counts[d] != s.counts[d]) return false;
return true;
}
void tryIt (const int currval, const digitMultiset& s,
const int digit, vector<int>& answers) {
digitMultiset newS;
for (int d = digit; d >= 2; d--) {
if (currval % d == 0) {
int quotient = currval / d;
newS = s;
newS.counts[d]++;
if (hasDigits (quotient, newS))
answers.push_back (quotient);
tryIt (quotient, newS, d, answers);
}
}
}
void seedProduct (const int val) {
vector<int> answers;
tryIt (val, empty, 9, answers);
int temp = val;
bool allOnes = true;
while (temp > 0) {
if (temp % 10 != 1) {
allOnes = false;
break;
}
temp /= 10;
}
if (allOnes)
answers.push_back(val);
int count = answers.size();
if (count > 0) {
if (count == 1)
cout << val << " has seed product " << answers[0] << endl;
else {
cout << val << " has " << count << " seed products: ";
for (int& ans : answers)
cout << ans << " ";
cout << endl;
}
}
}