LuoguP6188 [NOI Online #1 入門組] 文具訂購 題解
阿新 • • 發佈:2021-12-24
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\)
- \(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;
}