程式設計題 京東2016 買糖果

2021-07-30 11:58:19 字數 3871 閱讀 9804

**寫的有點繁瑣,歡迎指正~

題目描述

某糖果公司專門生產兒童糖果,它最受兒童歡迎的糖果有a1、a2兩個序列,均採用盒式包裝。包裝好的a1類糖果體積為乙個儲存單位,而包裝好的a2類糖果體積正好是a1類的兩倍。

這兩類糖果之所以廣受兒童歡迎,是因為糖果中含有公司獨家研發的魔幻因子。a1或a2序列中的糖果,看起來包裝可能是一樣的,但因為其中的魔幻因子含量不同被細分為不同的產品。

臨近傳統節日,公司的糖果供不應求。作為乙個精明的糖果分銷商,小東希望能夠藉此大賺一筆,於是帶著現金開著貨車來公司提貨。貨車的容量是確定的,小東希望採購的糖果能夠盡可能裝滿貨車,且糖果的魔幻因子總含量最高。只要不超出貨車容量,糖果總可以裝入貨車中。

輸入

輸入中有多組測試資料。每組測試資料的第一行有兩個整數n和v,1<=n<=10^5, 1<=v<=10^9,n為可供選購糖果數量,v為貨車的容量。

隨後n行為糖果的具體資訊,第一行編號為1,第二行編號為2,以此類推,最後一行編號為n。

每行包含兩個整數ti和pi,1<=ti<=2, 1<=pi<=10^4,ti為糖果所屬的序列,1為a1、2為a2,pi則是其中的魔幻因子含量。

輸出

對每組測試資料,先在單獨的一行中輸出能採購的糖果中的魔幻因子最高含量,

之後在單獨的行中按編號從小到大的順序輸出以空格分隔的糖果編號,

若有多組糖果組合均能滿足要求,輸出編號最小的組。

若沒有糖果能夠滿足要求,則在第一行中輸出0,第二行輸出「no」。

思路

容易進入的誤區是認為給定的區間過大,無法用一般的方法來做。而實際上10^9是可以接受的,求和的最大值是10^9 * 10^4 = 10^13,使用long long可以進行計算;佇列中放入10^5項也是可以接受的。

本題只有兩類編號,所以可以不使用01揹包的方法。假設選取編號1的糖果x個,編號2的糖果y個,

則x+2*y<=v,即2個編號1的糖果和1個編號2的糖果占用的容積相等,每次要麼選取兩個編號1的糖果,要麼選取1個編號2的糖果。

具體做法

用兩個容器分別儲存編號1的糖果和編號2的糖果,容器中需要儲存的內容包括每種糖果的索引編號,魔幻因子,並且按照魔幻因子排序。所以考慮使用map>來儲存(注意:這裡需要使用vector來儲存每種糖果的索引編號,因為具有相同魔幻因子的糖果可能對映到多個索引編號,雖然題目中沒有提到允許重複,但是更沒有提到說不重複,所以今後需要注意重複因素,這一點是在執行測試資料時才意識到的)

按照魔幻因子從大到小分別遍歷兩個map,每次從編號1的map中提取魔幻因子最高的兩個糖果sum1=magic1+magic2,和編號2的map中魔幻因子最高的乙個糖果sum2=magic3進行比較。如果sum1>sum2,則選取magic1和magic2;如果sum1v==1,則有兩種行為,一種是再放入乙個編號1的糖果,另一種是取出最近一次放入的編號1的糖果,使用編號2的糖果進行替換。

所以這裡還需要進行一次判斷!!!如果編號1中還有糖果magic1,記錄上一次放入的編號1的糖果prev,如果magic1+prev大於編號2的糖果,則選取magic1;如果小於,則選取編號2的糖果;如果等於,則判斷三者索引編號的前後關係再做決定。

注意:v==1時仍需要做一次判斷,切勿直接選取編號1的糖果進行填充!!

**寫的有點繁瑣,歡迎指正~

#include 

#include

#include

#include

//using

namespace

std;

typedef

long

long ll;

//int main()

else

if (type == 2)

i++;

}if (v < 1)

map>::reverse_iterator oneindex1 = ones.rbegin();

map>::reverse_iterator oneindex2 = ones.rbegin();

//注意,這裡需要判斷一下ones是否為空,使用rend()++會報錯的

if (oneindex1 != ones.rend() && (oneindex1->second).size() == 1) oneindex2++;

map>::reverse_iterator twoindex = twos.rbegin();

ll num = v;

//需要記錄最近一次選取的編號1的糖果的magic值以及對應的索引編號

int prev[2] = ;

while (num > 1)

else

if (oneindex1->second.front() > twoindex->second.front()

|| oneindex2->second.front() > twoindex->second.front())

isonemove = false;

}if (isonemove)//選取oneindex1和oneindex2

else

if (oneindex2->second.size() == 1)

else

if (oneindex2->second.size() == 0)

}else

//選取twoindex

num -= 2;//容量減2

}//只加入oneindex1和oneindex2

else

if (oneindex2 != ones.rend() && twoindex == twos.rend())

else

if (oneindex2->second.size() == 1)

else

if (oneindex2->second.size() == 0)

}else

if (oneindex2 == ones.rend() && twoindex != twos.rend())

}if (isonemove)

else

}else

if (oneindex2 == ones.rend() && twoindex == twos.rend())

break;}}

if (num == 1 && oneindex1 != ones.rend())

}if (isundo)

result.pop();

while (!temp.empty())

result.push(twoindex->second[0]);}}

else

//仍然選擇1

num--;

}else

if (num == 1 && oneindex1 == ones.rend())

}if (isundo)

result.pop();

while (!temp.empty())

result.push(twoindex->second[0]);}}

else

if (oneindex1 != ones.rend())

num--;

}if (maxsum > 0)

cout

<< maxsum << endl;

else

cout

<< 0

<< endl << "no"

<< endl;

while (!result.empty())

}return

0;}

程式設計題 吃糖果

程式設計題 吃糖果 名名的媽媽從外地出差回來,帶了一盒好吃又精美的巧克力給名名 盒內共有 n 塊巧克力,20 n 0 媽媽告訴名名每天可以吃一塊或者兩塊巧克力。假設名名每天都吃巧克力,問名名共有多少種不同的吃完巧克力的方案。例如 如果n 1,則名名第1天就吃掉它,共有1種方案。如果n 2,則名名可以...

程式設計題 買蘋果

小易去附近的商店買蘋果,奸詐的商販使用了 交易,只提供6個每袋和8個每袋的包裝 包裝不可拆分 可是小易現在只想購買恰好n個蘋果,小易想購買盡量少的袋數方便攜帶。如果不能購買恰好n個蘋果,小易將不會購買。輸入描述 輸入乙個整數n,表示小易想購買n 1 n 100 個蘋果 輸出描述 輸出乙個整數表示最少...

程式設計題 買蘋果

小易去附近的商店買蘋果,奸詐的商販使用了 交易,只提供6個每袋和8個每袋的包裝 包裝不可拆分 可是小易現在只想購買恰好n個蘋果,小易想購買盡量少的袋數方便攜帶。如果不能購買恰好n個蘋果,小易將不會購買。輸入描述 輸入乙個整數n,表示小易想購買n 1 n 100 個蘋果 輸出描述 輸出乙個整數表示最少...