LuoguP6188 [NOI Online #1 入门组] 文具订购 题解
Content
小明想用 \(n\) 块钱购买 \(3\) 个物品:
- 圆规,每个7块。
- 笔,每支4块。
- 笔记本,每本3块。
同时,他还有3个要求:
设圆规、笔、笔记本购买的数量分别是 \((a,b,c)\),则:
- \(n\)块钱必须全部花完,即 \(7a+4b+3c=n\)。
- 在满足第一个要求的前提下,成套的数目最大,即满足 \(\min{(a,b,c)}\) 为最大值。
- 在满足第二个要求的前提下,总数量最大,即满足 \(a+b+c\) 尽量大。
此时的最优解仅有一个,请求出这个最优解。
数据范围:\(0\leqslant n\leqslant 10^5\)。
Solution
来个更暴力的。
设 \(x=n\div 14,y=n\bmod 14\),最优解为 \((a_0,b_0,c_0)\)。(这里的 \(\div\) 指整除)
我们直接可以根据\(y\)进行分类讨论:
- \(y=0\),此时正好成套,此时 \((a_0,b_0,c_0)=(x,x,x)\)。
- \(y=1\),那这样子怎么办?没法再买了。没关系,腾出一个 \(14\) 元不行吗?当然,如果恰好只有 \(1\) 块钱,那就真的无解了。否则,腾出一个 \(14\) 元来,套数减 \(1\),这时剩下的钱数变成了 \(15\) 元。因为这已经是成套数目最大的情况了,所以此时我们设法将总数量最大化,即尽量买花钱少的物品。我们欣喜地发现,在这个情况中,剩下 \(15\) 块钱正好可以买 \(5\) 个笔记本,所以此时 \((a_0,b_0,c_0)=(x-1,x-1,x+4)\)。
- \(y=2\),跟 \(y=1\) 时的做法类似,也是腾出 \(14\) 块钱。此时剩下 \(16\) 块钱,我们发现,最优方案此时是再购买 \(4\) 个笔记本,\(1\) 支笔。所以此时 \((a_0,b_0,c_0)=(x-1,x,x+3)\)。当然如果正好只有 \(2\) 块钱的话就真的无解了。
- \(y=3\),正好可以买 \(1\) 本笔记本,此时 \((a_0,b_0,c_0)=(x,x,x+1)\)。
- \(y=4\),正好可以买 \(1\) 支笔,此时 \((a_0,b_0,c_0)=(x,x+1,x)\)。
- \(y=5\),跟 \(y=1\) 和 \(y=2\) 时的做法类似,腾出 \(14\) 元后就有了 \(19\) 元,此时正好可以买 \(5\) 本笔记本,\(1\) 支笔,所以 \((a_0,b_0,c_0)=(x-1,x,x+4)\)。当然如果正好只有 \(5\) 块钱的话就真的无解了。
- \(y=6\),正好可以买 \(2\) 本笔记本,此时 \((a_0,b_0,c_0)=(x,x,x+2)\)。
- \(y=7\),正好可以买 \(1\) 支笔,\(1\) 本笔记本,此时 \((a_0,b_0,c_0)=(x,x+1,x+1)\)。
- \(y=8\),正好可以买 \(2\) 支笔,此时 \((a_0,b_0,c_0)=(x,x+2,x)\)。
- \(y=9\),正好可以买 \(3\) 本笔记本,此时 \((a_0,b_0,c_0)=(x,x,x+3)\)。
- \(y=10\),正好可以买 \(1\) 支笔,\(2\) 本笔记本,此时 \((a_0,b_0,c_0)=(x,x+1,x+2)\)。
- \(y=11\),正好可以买 \(2\) 支笔,\(1\) 本笔记本,此时 \((a_0,b_0,c_0)=(x,x+2,x+1)\)。
- \(y=12\),正好可以买 \(4\) 本笔记本,此时 \((a_0,b_0,c_0)=(x,x,x+4)\)。
- \(y=13\),正好可以买 \(1\) 支笔,\(3\) 本笔记本,此时 \((a_0,b_0,c_0)=(x,x+1,x+3)\)。
所有情况都讨论完了。
没错,完了。
接下来奉上最暴力的代码。
Code
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
using namespace std;
int n, a, b, c;
//成套的数目尽量大,所以尽量多买14元
int main() {
scanf("%d", &n);
int p = n / 14;
switch(n % 14) {
case 0: {
// if(!p) printf("-1");
printf("%d %d %d", p, p, p);
break;
}
case 1: {
if(n < 14) printf("-1");
else printf("%d %d %d", p - 1, p - 1, p + 4);
break;
}
case 2: {
if(n < 14) printf("-1");
else printf("%d %d %d", p - 1, p, p + 3);
break;
}
case 3: {
printf("%d %d %d", p, p, p + 1);
break;
}
case 4: {
printf("%d %d %d", p, p + 1, p);
break;
}
case 5: {
if(n < 14) printf("-1");
else printf("%d %d %d", p - 1, p, p + 4);
break;
}
case 6: {
printf("%d %d %d", p, p, p + 2);
break;
}
case 7: {
printf("%d %d %d", p, p + 1, p + 1);
break;
}
case 8: {
printf("%d %d %d", p, p + 2, p);
break;
}
case 9: {
printf("%d %d %d", p, p, p + 3);
break;
}
case 10: {
printf("%d %d %d", p, p + 1, p + 2);
break;
}
case 11: {
printf("%d %d %d", p, p + 2, p + 1);
break;
}
case 12: {
printf("%d %d %d", p, p, p + 4);
break;
}
case 13: {
printf("%d %d %d", p, p + 1, p + 3);
break;
}
}
return 0;
}