小明的賬單(信息學奧賽一本通 1372)


【題目描述】

小明在一次聚會中,不慎遺失了自己的錢包,在接下來的日子,面對小明的將是一系列的補卡手續和堆積的賬單… 在小明的百般懇求下,老板最終同意延緩賬單的支付時間。可老板又提出,必須從目前還沒有支付的所有賬單中選出面額最大和最小的兩張,並把他們付清。還沒有支付的賬單會被保留到下一天。 請你幫他計算出支付的順序。

【輸入】

第1行:一個正整數N(N≤15,000),表示小明補辦銀聯卡總共的天數。

第2行到第N+1 行:每一行描述一天中收到的帳單。先是一個非負整數M≤100,表示當天收到的賬單數,后跟M個正整數(都小於1,000,000,000),表示每張帳單的面額。

輸入數據保證每天都可以支付兩張帳單。

【輸出】

輸出共N 行,每行兩個用空格分隔的整數,分別表示當天支付的面額最小和最大的支票的面額。

【輸入樣例】

4 3 3 6 5 2 8 2 3 7 1 7 0

【輸出樣例】

3 6 2 8 1 7 5 7


一開始看到這道題,我的困擾是如何取出小根堆里的最大值(或者是大根堆里的最小值),后來干脆定義了兩個優先隊列,一個專用取最大值,一個取最小值(其實是有漏洞的,因為兩個隊列里的值沒有實時更新,會出現重疊)

 一開始的代碼的這樣的:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 priority_queue<int> h;
 4 priority_queue<int,vector<int>,greater<int> >q;
 5 int main()
 6 {
 7     int n;cin>>n;
 8     while(n--)
 9     {
10         int m,x;cin>>m;
11         for(int i=1;i<=m;i++)
12         {
13             cin>>x;
14             h.push(x);
15             q.push(x);
16         }
17         cout<<q.top()<<' '<<h.top()<<endl;
18         h.pop();q.pop();
19     }
20     return 0;
21 }

在一本通網站上提交了之后竟然還得了80分,看來數據有點水(主要靠運氣)

后來仔細想了想這道題目其實肥腸簡單,用下multiset就可以啦,所以說STL是很重要弟,可以減少不少的代碼量呢

(關於multiset的用法,請看☟

【C++ STL】Set和Multiset 怎么用咧↓↓↓ - endl\n - 博客園
https://www.cnblogs.com/ljy-endl/p/11257825.html)

本題代碼如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 multiset<int> st;//定義int類型的set
 4 int main()
 5 {
 6     int n;
 7     cin>>n;
 8     st.clear();
 9     for(int i=1;i<=n;i++)
10     {
11         int m;
12         cin>>m;
13         for(int j=1;j<=m;j++)
14         {
15             int a;
16             cin>>a;
17             st.insert(a);//插入元素
18         }
19 
20         cout<<*st.begin()<<" ";//輸出最小元素
21         st.erase(st.begin());//刪除set中最小元素
22         cout<<*(--st.end())<<endl;//輸出最大元素
23         st.erase(--st.end());//刪除set中最大元素
24     }
25 
26     return 0;
27 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM