文具订购(网络赛)

【题目描述】
小明的班上共有 n 元班费,同学们准备使用班费集体购买 3 种物品:

  1. 圆规,每个 7 元。
  2. 笔,每支 4 元。
  3. 笔记本,每本 3 元。
    小明负责订购文具,设圆规,笔,笔记本的订购数量分别为 a,b,c,他订购的原则依次如下:
  4. n 元钱必须正好用光,即 7a+4b+3c=n。
  5. 在满足以上条件情况下,成套的数量尽可能大,即 a,b,c 中的最小值尽可能大。
  6. 在满足以上条件情况下,物品的总数尽可能大,即 a+b+c 尽可能大。
    请你帮助小明求出满足条件的最优方案。可以证明若存在方案,则最优方案唯一。
    【输入格式】
    从文件 order.in 中读入数据。
    仅一行一个整数 n 表示班费数量。
    【输出格式】
    输出到文件 order.out 中。
    若方案不存在则输出 -1。否则输出一行三个用空格分隔的非负整数 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 也是满足条件 1,2 的方案,但对于条件 3,该方案只买了 7 个物品,不如 a=1,b=2,c=6 的方案。
    【数据范围与提示】
    对于测试点 1 ∼ 6:n ≤ 14。
    对于测试点 7 ∼ 12:n 是 14 的倍数。
    对于测试点 13 ∼ 18:n ≤ 100。
    对于所有测试点:0 ≤ n ≤ 10 5 。

我们来分析条件1 2 3
第一:用n/14,就能满足条件2(在满足以上条件情况下,成套的数量尽可能大,即 a,b,c 中的最小值尽可能大。)
第二:将n%14的余数进行处理,就能满足条件1(n 元钱必须正好用光,即 7a+4b+3c=n)和3(在满足以上条件情况下,物品的总数尽可能大,即 a+b+c 尽可能大)。

这个算打表?(后面提供了第二种方法)

方法一:打表(直观)

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n,a=0,b=0,c=0;
	cin>>n;
	if(n == 1 || n == 2 || n == 5)
		cout<<"-1";
	else{
		if(n%14 == 0)
		{
			a=a+n/14;
			b=b+n/14;
			c=c+n/14;
		}
		if(n%14 == 1)
		{
			a=a+n/14-1;
			b=b+n/14+2;
			c=c+n/14;
		}
		if(n%14 == 2)
		{
			a=a+n/14-1;
			b=b+n/14;
			c=c+n/14+3;
		}
		if(n%14 == 3)
		{
			a=a+n/14;
			b=b+n/14;
			c=c+n/14+1;
		}
		if(n%14 == 4)
		{
			a=a+n/14;
			b=b+n/14+1;
			c=c+n/14;
		}
		if(n%14 == 5)
		{
			a=a+n/14-1;
			b=b+n/14;
			c=c+n/14+4;
		}
		if(n%14 == 6)
		{
			a=a+n/14;
			b=b+n/14;
			c=c+n/14+2;
		}
		if(n%14 == 7)
		{
			a=a+n/14;
			b=b+n/14+1;
			c=c+n/14+1;
		}
		if(n%14 == 8)
		{
			a=a+n/14;
			b=b+n/14+2;
			c=c+n/14;
		}
		if(n%14 == 9)
		{
			a=a+n/14;
			b=b+n/14;
			c=c+n/14+3;
		}
		if(n%14 == 10)
		{
			a=a+n/14;
			b=b+n/14+1;
			c=c+n/14+2;
		}
		if(n%14 == 11)
		{
			a=a+n/14;
			b=b+n/14+2;
			c=c+n/14+1;
		}
		if(n%14 == 12)
		{
			a=a+n/14;
			b=b+n/14;
			c=c+n/14+4;
		}
		if(n%14 == 13)
		{
			a=a+n/14;
			b=b+n/14+1;
			c=c+n/14+3;
		}
		cout<<a<<" "<<b<<" "<<c;	
	}
	return 0;
}

方法二:变相打表(但是没有方法一直观)

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n,a=0,b=0,c=0;
	cin>>n;
	if(n == 1 || n == 2 || n == 5)
		cout<<"-1";
	else{
		int r = n%14;
		a=a+n/14;
		b=b+n/14;
		c=c+n/14;
		if(r){
			if(r == 1 || r == 2 || r == 5)//余数为1 2 5 
				r = r+7,a = a-1;
			if(r%3 == 0){//余数为3 6 9 12 
				c += r/3;
			}else if(r%4 == 0){//余数为4 8 
				b += r/4;
			}else{//还剩7 10 11 13 
				if(r == 7 || r == 10 || r == 13){
					c = c + r/3 - 1;
					b += 1;
				}else{// 还剩11
					c += 1;
					b += 2;
				}			
			}
		}
		cout<<a<<" "<<b<<" "<<c;	
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39053800/article/details/104721023