题目描述:小B每次去超市就将要购买的商品列个清单,每个项目买一个,若要买多个,就写多个商品名。例如:apple; banana; apple; peach; apple; apple; banana。小B太激动了,来超市来得太早,以至于服务员还没有将价签贴在商品上。小B看到价签还在柜台上,她想知道这次购物她最好和最坏情况下会花费多少钱。
输入:有多组测试数据,每组测试数据的第一行是两个整数n和m,分别表示价签的数量和小B购买清单上的商品数目。第二行用空格分开的正整数为物品价格,随后m行为购买清单中的物品名称,保证清单中的不同物品种类不超过n,而且商店有小B清单上的所有物品。
输出:对每组测试数据,在单独的行中输入两个数a和b,表示购买清单上所有的物品可能需要的最小和最大费用。
样例输入:
5 3
4 2 1 10 5
apple
orange
mango
6 5
3 5 1 6 8 1
peach
grapefruit
banana
orange
orange
样例输出:
7 19
11 30
思路:
1. 需要对商品清单进行整理,将名称想等的物品合并给出重复物品的个数,将列表以商品个数从大到小排列
2. 对价格进行从小到大排列。
用钱最少的情况是:最多的东西用最便宜的价格购买,次多的东西用第二便宜的价格购买,等等。。
用钱最多的情况是:最多的东西用最贵的价格购买,次多的东西用第二贵的价格购买,等等。。
代码如下:
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
#include <vector>
using namespace std;
bool cmp(const pair<string, int> &a, const pair<string, int> &b)
{
if (a.second > b.second)
return true;
else return false;
}
int main(void)
{
int n, m;
vector<int> prices;
map<string, int> thingsList;
map<string, int> ::iterator itor = thingsList.begin();
vector<pair<string, int> > things;
while (cin >> n >> m)
{
while(n--)
{
int temp;
cin >> temp;
prices.push_back(temp);
}
sort(prices.begin(), prices.end());
while(m--)
{
string strTemp;
cin >> strTemp;
itor = thingsList.find(strTemp);
if (itor == thingsList.end())
{
thingsList.insert(make_pair(strTemp, 1));
}
else
{
itor -> second ++;
}
}
for (itor = thingsList.begin(); itor != thingsList.end(); ++itor)
{
things.push_back(*itor);
}
sort(things.begin(), things.end(), cmp);
int little = 0;
int much = 0;
int prices_first = 0;
int prices_last = prices.size() - 1;
for (unsigned int i = 0; i < things.size(); ++i)
{
much += prices[prices_last--] * things[i].second;
little += prices[prices_first++] * things[i].second;
}
cout << little << " " << much << endl;
}
}