文具訂購(網絡賽)

【題目描述】
小明的班上共有 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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章