买橘子
思路
这道题说的是,小明要买恰好 个橙子,商贩只卖整袋的,每袋要么 6 个要么 8 个,问最少买几袋能凑出恰好
个,凑不出就输出
。
最直接的做法就是枚举。我们枚举用了多少袋 6 个装的,设为 袋,那么剩下的
个就必须全用 8 个装的袋子来凑。只要
能被 8 整除,就说明这种分配方案可行,此时袋数就是
。我们在所有可行方案里取最小值就好了。
为什么这样做是对的?因为 6 个装的袋数最多用 袋,所以枚举范围是有限的。而且我们要最少袋数,8 个装的袋子装得更多,所以尽量多用 8 个装的会更优。枚举的过程天然会覆盖到最优解。
举个例子:,枚举
时剩 20,
;
时剩
,
,袋数
。所以答案是 3。
代码
#include <bits/stdc++.h>
using namespace std;
int main(){
int n;
cin >> n;
int ans = INT_MAX;
for(int i = 0; i <= n/6; i++){
int rem = n - i*6;
if(rem % 8 == 0){
ans = min(ans, i + rem/8);
}
}
cout << (ans == INT_MAX ? -1 : ans) << endl;
return 0;
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int ans = Integer.MAX_VALUE;
for (int i = 0; i <= n / 6; i++) {
int rem = n - i * 6;
if (rem % 8 == 0) {
ans = Math.min(ans, i + rem / 8);
}
}
System.out.println(ans == Integer.MAX_VALUE ? -1 : ans);
}
}
n = int(input())
ans = float('inf')
for i in range(n // 6 + 1):
rem = n - i * 6
if rem % 8 == 0:
ans = min(ans, i + rem // 8)
print(-1 if ans == float('inf') else ans)
const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin });
rl.on('line', (line) => {
const n = parseInt(line.trim());
let ans = Infinity;
for (let i = 0; i <= Math.floor(n / 6); i++) {
const rem = n - i * 6;
if (rem % 8 === 0) {
ans = Math.min(ans, i + rem / 8);
}
}
console.log(ans === Infinity ? -1 : ans);
rl.close();
});
复杂度分析
- 时间复杂度:
,即
。枚举 6 个装的袋数,最多循环
次。
- 空间复杂度:
,只用了几个变量。

京公网安备 11010502036488号