问题:在一个平行宇宙中,麦当劳的麦乐鸡块分为 7 块装、13 块装和 29 块装。有一天,你的老板让你出去购买正好为 n 块(0 < n <= 10000)的麦乐鸡块回来,请提供一个算法判断是否可行。
说明:除了三重循环的解法,有没有效率更高一点的方法。求大佬指点。
问题:在一个平行宇宙中,麦当劳的麦乐鸡块分为 7 块装、13 块装和 29 块装。有一天,你的老板让你出去购买正好为 n 块(0 < n <= 10000)的麦乐鸡块回来,请提供一个算法判断是否可行。
说明:除了三重循环的解法,有没有效率更高一点的方法。求大佬指点。
function countAll(i, j, k, total) {
if ((i * 7 + j * 13 + 29 * k) > total) {
return false;
}
if (total === 7 || total === 13 || total === 29) {
return true;
}
if (isVoid(i, j, k, total)) {
return true;
} else {
return countAll(i, j, k + 1 , total) || countAll(i , j + 1, k , total) || countAll(i + 1, j , k , total) || false;
}
}
function isVoid(i, j, k, total) {
let value = i * 7 + j * 13 + 29 * k;
if (total % value == 0 && value !== 0) {
console.log(i , j , k);
return true;
}
return false;
}
var res = countAll(0, 0 , 0 ,9892);
console.log(res);
递归实现
在范围内进行枚举,将中间过程存入桶。具体的,桶的初始值默认为 0,接下来进行递归:
bool resBucket[10005]; // 范围为 1~10000
bool check ( ) {
memset (resBucket, 0, sizeof (resBucket)); // 默认为 false
queue <int> q; // 队列里存入所有合理的数
q.push (0); // 一个不买显然合理
while (!q.empty ( )) { // 当有待查验的数时:
int tmp = q.front ( ); q.pop ( ); // 记录现在处理的合理的数
if (tmp > n) continue; // 越界,无需查验
if (tmp == n) return true; // 可行,结束
if (resBucket[tmp] == true) continue; // 重复,无需再枚举
resBucket[tmp] = true; // 记录
q.push (tmp + 7); q.push (tmp + 13); q.push (tmp + 29);
// 若 tmp 可以,多买这三种中任何一个都可以
}
return false; // 所有可行方案全遍历过了,不可行,结束
}
8 回答6.4k 阅读
1 回答3.4k 阅读✓ 已解决
1 回答4.2k 阅读✓ 已解决
3 回答2.3k 阅读✓ 已解决
2 回答3.2k 阅读
2 回答3.9k 阅读
3 回答1.7k 阅读✓ 已解决