2018 ICPC青岛-books(思维题)
DreamGrid went to the bookshop yesterday. There are nn books in the bookshop in total. Because DreamGrid is very rich, he bought the books according to the strategy below:
Check the nn books from the 1st one to the nn-th one in order.
For each book being checked now, if DreamGrid has enough money (not less than the book price), he’ll buy the book and his money will be reduced by the price of the book.
In case that his money is less than the price of the book being checked now, he will skip that book.
BaoBao is curious about how rich DreamGrid is. You are asked to tell him the maximum possible amount of money DreamGrid took before buying the books, which is a non-negative integer. All he knows are the prices of the nn books and the number of books DreamGrid bought in total, indicated by mm.
Input
There are multiple test cases. The first line of the input contains an integer TT, indicating the number of test cases. For each test case:
The first line contains two integers nn and mm (1 ≤ n ≤ 1e5 0≤m≤n), indicating the number of books in the bookshop and the number of books DreamGrid bought in total.
The second line contains nn non-negative integers a1,a2,a3…an,(0-1e9)where ai indicates the price of the ii-th book checked by DreamGrid.
It’s guaranteed that the sum of nn in all test cases will not exceed 10^6。
Output
For each test case output one line.
If it’s impossible to buy mm books for any initial number of money, output “Impossible” (without quotes).
If DreamGrid may take an infinite amount of money, output “Richman” (without quotes).
In other cases, output a non-negative integer, indicating the maximum number of money he may take.
Sample Input
4
4 2
1 2 4 8
4 0
100 99 98 97
2 2
10000 10000
5 3
0 0 0 0 1
Sample Output
6
96
Richman
Impossible
昨天,DreamGrid去了书店。书店里总共有nn本书。因为DreamGrid非常有钱,所以他按照以下策略购买了这些书:
从第1到第nn顺序检查nn本书。
对于现在正在检查的每本书,如果DreamGrid拥有足够的钱(不少于本书价格),他将购买该书,并且他的钱将减少该书的价格。
如果他的钱少于现在要检查的书的价格,他将跳过那本书。
宝宝对DreamGrid的丰富程度感到好奇。您被要求告诉他DreamGrid在购买书籍之前所能获得的最大金额,这是一个非负整数。他所知道的只是nn本书的价格和DreamGrid总共购买的本书的数量,以mm表示。
输入
有多个测试用例。输入的第一行包含一个整数TT,表示测试用例的数量。对于每个测试用例:
第一行包含两个整数nn和mm(1≤n≤1e5 0≤m≤n),指示书店中的图书数量和DreamGrid总共购买的图书数量。
第二行包含nn个非负整数a1,a2,a3 … an,(0-1e9),其中ai表示DreamGrid检查的第二本书的价格。
保证所有测试用例中nn的总和不超过10 ^ 6。
输出
对于每个测试用例,输出一行。
如果不可能用任何初始金额购买mm的书,则输出“不可能”(不带引号)。
如果DreamGrid可能花费不计其数的钱,请输出“ Richman”(不带引号)。
在其他情况下,输出一个非负整数,表示他可以拿走的最大数目。
题目链接
这道题是2018ICPC的题目,是一道思维题,想不明白没法做,只要思路通了就很简单,题意是书店T个测试样例,对于每个样例,书店共有n本书,要从其中买m本书,求恰好能买走m本书,最多带的钱是多少。如果能全买走,就输出Richman,如果免费书的数量大于m的数量就impossible,想明白这点后我们可以分成以下几种情况考虑:第一:m==n的时候,这时候直接输出richman即可。第二种:免费的书,即价格为0 的书数量大于m,这时候直接输出impossible即可。第三种:也就是正常情况下,我们还是要先统计0的个数z,因为0的时候是可以直接拿走的,统计完以后我们用m-z,得到剩下要买书的数量,从第一本遍历过来就可以,因为题意是买书的人从第一本依次往后,如果能买得起就买,买不起就跳过,最后买够了m-z后,ans加剩余的书价钱的最小值-1就可以(因为买完以后他什么都买不起了),对于m-z等于0,则说明他要买m本书,书架里有m本免费的书,这时候直接统计其他不为0 的书的最小值-1即可。最后输出ans。AC代码
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int _max=1e5+50;
typedef long long ll;
int a[_max];
int main()
{
int t;
scanf("%lld",&t);
while(t--)
{
int n,m,z=0;//z用于统计0的个数
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
if(a[i]==0)
z++;//统计0
}
if(z>m)//情况2
printf("Impossible\n");
else if(m==n)//情况1
printf("Richman\n");
else//情况3
{
int i;
m-=z;
ll ans=0;
for(i=0;i<n;i++)//除0以外,从第一本书遍历,ans+=a[i]
{
if(m==0)//一定要先判断,因为考虑到m一开始就等于0的情况
break;
if(a[i])
{
ans+=a[i];
m--;
}
}
int x=0x3f3f3f3f;//找剩下的不为0 的最大值
for(int j=i;j<n;j++)
if(a[j])
x=min(x,a[j]);
ans+=(x-1);
printf("%lld\n",ans);
}
}
return 0;
}
ps:我认为理解这道题应该先理解他买书的规则,从第一本书开始遍历,买得起就ans加,买不起就跳过继续往下。所以我们不用排序,直接遍历过来就可。最后买够了以后再加上一个最小值就能AC。