2.0 KiB
2.0 KiB
id, title, challengeType, forumTopicId, dashedName
id | title | challengeType | forumTopicId | dashedName |
---|---|---|---|---|
5900f3ba1000cf542c50fecd | 問題 78: 硬貨の分割 | 5 | 302191 | problem-78-coin-partitions |
--description--
n
枚の硬貨を分ける方法が何通りあるかを、{p}(n)
で表すことにします。 例えば、5 枚の硬貨はちょうど 7 通りの方法で分けることができるので、{p}(5) = 7
となります。
硬貨のまとまり |
---|
OOOOO |
OOOO O |
OOO OO |
OOO O O |
OO OO O |
OO O O O |
O O O O O |
{p}(n)
が divisor
で割り切れる場合の n
の最小値を求めなさい。
--hints--
coinPartitions(7)
は数値を返す必要があります。
assert(typeof coinPartitions(7) === 'number');
coinPartitions(7)
は 5
を返す必要があります。
assert.strictEqual(coinPartitions(7), 5);
coinPartitions(10000)
は 599
を返す必要があります。
assert.strictEqual(coinPartitions(10000), 599);
coinPartitions(100000)
は 11224
を返す必要があります。
assert.strictEqual(coinPartitions(100000), 11224);
coinPartitions(1000000)
は 55374
を返す必要があります。
assert.strictEqual(coinPartitions(1000000), 55374);
--seed--
--seed-contents--
function coinPartitions(divisor) {
return true;
}
coinPartitions(7);
--solutions--
function coinPartitions(divisor) {
const partitions = [1];
let n = 0;
while (partitions[n] !== 0) {
n++;
partitions.push(0);
let i = 0;
let pentagonal = 1;
while (pentagonal <= n) {
const sign = i % 4 > 1 ? -1 : 1;
partitions[n] += sign * partitions[n - pentagonal];
partitions[n] = partitions[n] % divisor;
i++;
let k = Math.floor(i / 2) + 1;
if (i % 2 !== 0) {
k *= -1;
}
pentagonal = Math.floor((k * (3 * k - 1)) / 2);
}
}
return n;
}