题目描述
小明的班上共有 n n n 元班费,同学们准备使用班费集体购买 3 3 3 种物品:
圆规,每个
7
7
7 元。
笔,每支
4
4
4 元。
笔记本,每本
3
3
3 元。
小明负责订购文具,设圆规,笔,笔记本的订购数量分别为
a
,
b
,
c
a,b,c
a,b,c,他订购的原则依次如下:
- n n n 元钱必须正好用光,即 7 a + 4 b + 3 c = n 7a+4b+3c=n 7a+4b+3c=n。
- 在满足以上条件情况下,成套的数量尽可能大,即 a , b , c a,b,c a,b,c 中的最小值尽可能大。
- 在满足以上条件情况下,物品的总数尽可能大,即 a + b + c a+b+c a+b+c 尽可能大。
请你帮助小明求出满足条件的最优方案。可以证明若存在方案,则最优方案唯一。
输入格式
输入仅一行一个整数,代表班费数量 n n n。
输出格式
如果问题无解,请输出 − 1 -1 −1。
否则输出一行三个用空格隔开的整数 a , b , c a, b, c a,b,c,分别代表圆规、笔、笔记本的个数。
输入输出样例
输入 #1 复制
1
输出 #1 复制
-1
输入 #2 复制
14
输出 #2 复制
1 1 1
输入 #3 复制
33
输出 #3 复制
1 2 6
说明/提示
样例输入输出 3 解释
a = 2 , b = 4 , c = 1 a=2,b=4,c=1 a=2,b=4,c=1 也是满足条件 1 , 2 1,2 1,2 的方案,但对于条件 3 3 3,该方案只买了 7 7 7 个物品,不如 a = 1 , b = 2 , c = 6 a=1,b=2,c=6 a=1,b=2,c=6 的方案。
数据规模与约定
- 对于测试点 1 ∼ 6 1 \sim 6 1∼6,保证 n ≤ 14 n \leq 14 n≤14。
- 对于测试点 7 ∼ 12 7 \sim 12 7∼12,保证 n n n 是 14 14 14 的倍数。
- 对于测试点 13 ∼ 18 13 \sim 18 13∼18,保证 n ≤ 100 n \leq 100 n≤100。
- 对于 100 % 100\% 100% 的数据,保证 0 ≤ n ≤ 1 0 5 0 \leq n \leq 10^5 0≤n≤105 。
思路
这么简单的一道题,考试时竟然没有注意到一个细(kēng)节(diǎn),实在是失策失策
好了,进入正题
说白了,就是求一元三次方程的非负整数解(其他的特殊要求先不管)
首先,我们要先判断 7 a + 4 b + 3 c = n 7a+4b+3c=n 7a+4b+3c=n 是否可以有非负整数解。
我们发现这个方程中 : a a a 的系数就等于 b b b 的系数加 c c c 的系数,即 7 = 3 + 4 7=3+4 7=3+4
所以,要判断是否有非负整数解,只要判断二元一次方程 3 x + 4 y = n 3x+4y=n 3x+4y=n 是否有非负整数解就可以了。
然后我们发现 g c d ( 3 , 4 ) = 1 gcd(3,4)=1 gcd(3,4)=1 ( 3 , 4 (\ 3,4 ( 3,4 的最大公因数是 1 ) 1\ ) 1 ), 也就是说,只要 n n n 大于 7 7 7 并且 n n n 是 1 1 1 的倍数,这个方程就一定有非负整数解。
例如 9 x + 12 y = n 9x+12y=n 9x+12y=n, g c d ( 9 , 12 ) = 3 gcd(9,12)=3 gcd(9,12)=3,所以,只要 n n n 大于 21 21 21 并且是 3 3 3 的倍数,那么这个方程就一定有非负整数解
你还可以自己去举更多的例子。
这样,我们就可以判断 7 x + 4 b + 3 c = n 7x+4b+3c=n 7x+4b+3c=n 这个方程是否有非负整数解了( 0 0 0 到 7 7 7 的自己可以算(còu),结果就是只有 1 1 1, 2 2 2, 5 5 5 没有非负整数解)。
然后,就是整道题目的核心
先说明,我讲的不是暴力,是分类讨论(加上一点数形结合、方程以及类比的思想)
分类讨论:关于 n m o d 7 n\ mod\ 7 n mod 7 的分类 ( 以下的分类都是在由负整数解的情况下所述的 )
比如说这幅图。
设 n = 7 k + x ( 0 ≤ x < 7 ) n=7k+x\ (\ 0\leq x\lt7\ ) n=7k+x ( 0≤x<7 )
- 当 n m o d 7 = 0 n\ mod\ 7=0 n mod 7=0 时,最优的方案就应该是把 k k k 分成两份,一份分给 7 7 7 ,另一份分给 3 , 4 3,4 3,4,如果不可以平均分,那么为了让买的总数最大,就应该把剩下的 1 1 1 个 7 7 7 给 3 , 4 3,4 3,4 。
- 当 n m o d 7 = 1 n\ mod\ 7=1 n mod 7=1 时,因为 3 3 3 和 4 4 4 无法拼出 1 1 1 ,所以我们要拆开一个 7 7 7 ,拿出来和 1 1 1 一起用两个 4 4 4 拼出,但是,如果可以拆出来两个 7 7 7 的话,那么就可以拼出五个 3 3 3 ,却少拼了一个 3 3 3 和一个 4 4 4 ,还是比前一种方案优,所以,只要可以拆出来两个 7 7 7 ,就要分给 3 3 3 ,否则就拆一个出来分给 4 4 4 。
- 当 n m o d 7 = 2 n\ mod\ 7=2 n mod 7=2 时,就要拿出一个 7 7 7 拼三个 3 3 3 ,如果拆两个的话,可以算一下,没有拆一个的方案优。
- 当 n m o d 7 = 3 n\ mod\ 7=3 n mod 7=3 时,那 x x x 就直接给 3 3 3 。
- 当 n m o d 7 = 4 n\ mod\ 7=4 n mod 7=4 时, x x x 就直接给 4 4 4 。
- 当 n m o d 7 = 5 n\ mod\ 7=5 n mod 7=5 时,就要加一个 7 7 7 ,得到 12 12 12,那么为了让买的总数最多,应该把这 12 12 12 都给 3 3 3 是最优的。
- 当 n m o d 7 = 6 n\ mod\ 7=6 n mod 7=6 时, x x x 就都给 3 3 3 就可以了
所以公式就是:
提示:一下所述的除法都是整除
- 当 n m o d 7 = 0 n\ mod\ 7=0 n mod 7=0 时, a = b = c = n ÷ 7 ÷ 2 = n ÷ 14 a=b=c=n\div7\div2=n\div14 a=b=c=n÷7÷2=n÷14
- 当 n m o d 7 = 1 n\ mod\ 7=1 n mod 7=1 时,如果 n ≤ 8 n\le8 n≤8 时 a = ( n ÷ 7 − 1 ) ÷ 2 , b = n ÷ 7 − a − 1 + 2 = n ÷ 7 − a + 1 , c = n ÷ 7 − a − 1 a=(n\div7-1)\div2\ ,\ b=n\div7-a-1+2=n\div7-a+1\ ,\ c=n\div7-a-1 a=(n÷7−1)÷2 , b=n÷7−a−1+2=n÷7−a+1 , c=n÷7−a−1,如果 n > 8 n>8 n>8 时 a = ( n ÷ 7 − 2 ) ÷ 2 = n ÷ 14 − 1 , b = n ÷ 7 − a − 2 + 2 = n ÷ 7 − a , c = n ÷ 7 − a − 2 a=(n\div7-2)\div2=n\div14-1\ ,\ b=n\div7-a-2+2=n\div7-a\ ,\ c=n\div7-a-2 a=(n÷7−2)÷2=n÷14−1 , b=n÷7−a−2+2=n÷7−a , c=n÷7−a−2
- 当 n m o d 7 = 2 n\ mod\ 7=2 n mod 7=2 时, a = ( n ÷ 7 − 1 ) ÷ 2 , b = n ÷ 7 − a − 1 , c = n ÷ 7 − a − 1 + 3 = n ÷ 7 − a + 2 a=(n\div7-1)\div2\ ,\ b=n\div7-a-1\ ,\ c=n\div7-a-1+3=n\div7-a+2 a=(n÷7−1)÷2 , b=n÷7−a−1 , c=n÷7−a−1+3=n÷7−a+2
- 当 n m o d 7 = 3 n\ mod\ 7=3 n mod 7=3 时, a = b = n ÷ 7 ÷ 2 = n ÷ 14 , c = n ÷ 7 ÷ 2 + 1 = n ÷ 14 + 1 a=b=n\div7\div2=n\div14\ ,\ c=n\div7\div2+1=n\div14+1 a=b=n÷7÷2=n÷14 , c=n÷7÷2+1=n÷14+1
- 当 n m o d 7 = 4 n\ mod\ 7=4 n mod 7=4 时, a = c = n ÷ 7 ÷ 2 , b = n ÷ 7 ÷ 2 + 1 a=c=n\div7\div2\ ,\ b=n\div7\div2+1 a=c=n÷7÷2 , b=n÷7÷2+1
- 当 n m o d 7 = 5 n\ mod\ 7=5 n mod 7=5 时, a = ( n ÷ 7 − 1 ) ÷ 2 , b = n ÷ 7 − a − 1 , c = n ÷ 7 − a − 1 + 4 = n ÷ 7 − a + 3 a=(n\div7-1)\div2\ ,\ b=n\div7-a-1\ ,\ c=n\div7-a-1+4=n\div7-a+3 a=(n÷7−1)÷2 , b=n÷7−a−1 , c=n÷7−a−1+4=n÷7−a+3
- 当 n m o d 7 = 6 n\ mod\ 7=6 n mod 7=6 时, a = b = n ÷ 7 ÷ 2 , c = n ÷ 7 ÷ 2 + 2 a=b=n\div7\div2\ ,\ c=n\div7\div2+2 a=b=n÷7÷2 , c=n÷7÷2+2
可能有点看不太清,换表格
x的值 | a的值 | b的值 | c的值 |
---|---|---|---|
n%7=0 | n÷14 | n÷7-n÷14 | n÷7-n÷14 |
n%7=1 | (n÷7-1)÷2 | n÷7-(n÷7-1)÷2+1 | n÷7-(n÷7-1)÷2-1 |
n%7=2,n≤8 | (n÷7-1)÷2 | n÷7-(n÷7-1)÷2-1 | n÷7-(n÷7-1)÷2 |
n%7=2,n>8 | n÷14-1 | n÷7-n÷14-1 | n÷7-n÷14+4 |
n%7=3 | n÷14 | n÷7-n÷14 | n÷7-n÷14+1 |
n%7=4 | n÷14 | n÷7-n÷14+1 | n÷7-n÷14 |
n%7=5 | (n÷7-1)÷2 | n÷7-(n÷7-1)÷2-1 | n÷7-(n÷7-1)÷2+3 |
n%7=6 | n÷14 | n÷7-n÷14 | n÷7-n÷14+2 |
注意,在所有的 b , c b,c b,c 中的 n ÷ 7 − n ÷ 14 n\div7-n\div14 n÷7−n÷14 绝对不可以改成 n ÷ 14 n\div14 n÷14 ,因为是整除
好了,不多说了,细(kēng)节(diǎn)不少
代码
#include<bits/stdc++.h>
using namespace std;
int n;
int main(){
scanf("%d",&n);
if(n==1||n==2||n==5)
printf("-1");
else if(n%7==0)
printf("%d %d %d",n/14,n/7-n/14,n/7-n/14);
else if(n%7==1)
if(n>8)
printf("%d %d %d",n/14-1,n/7-n/14-1,n/7-n/14+4);
else
printf("%d %d %d",(n/7-1)/2,n/7-(n/7-1)/2+1,n/7-(n/7-1)/2-1);
else if(n%7==2)
printf("%d %d %d",(n/7-1)/2,n/7-(n/7-1)/2-1,n/7-(n/7-1)/2+2);
else if(n%7==3)
printf("%d %d %d",n/14,n/14,n/14+1);
else if(n%7==4)
printf("%d %d %d",n/14,n/7-n/14+1,n/7-n/14);
else if(n%7==5)
printf("%d %d %d",(n/7-1)/2,n/7-(n/7-1)/2-1,n/7-(n/7-1)/2+3);
else if(n%7==6)
printf("%d %d %d",n/14,n/7-n/14,n/7-n/14+2);
return 0;
}