题目链接:http://acm.zzuli.edu.cn/problem.php?id=2482
时间限制: 1 Sec 内存限制: 128 MB
题目描述
在打扑克牌时,小新觉得无聊,于是便和小新新,小新新新聊了会天,当小新新和小新新新说自己已经刷了好多道题的时候,只刷了两百道的小新羞愧的低下了头。
小新:”不打了,我要回去刷题了。"
小新回到机房,打开了OJ,看到还有n道题目没有做。由于小新听学长说过:“整天刷水题就是在浪费时间,对你自身的水平的提升并没有什么太大的用处的。”所以小新决定从这些题目中挑选一些题目来做。
通过某种标准,我们可以将小新的水平表示为一个正整数g,同时也可以将题目的难度表示为正整数x。当小新刷一道难度为x的题,如果x<=g,那么则认为小新刷了一道水题,将花费1单位的时间,g不变;如果x>g,则认为小新刷了一道难题,小新的水平也将提升为x,同时会花费x-g+2的时间,但是如果题目太难了,小新也是做不出来的,小新只能做出来不超过自身水平z(z<=100)难度的题(即小新只能做出题目难度x<=g+z的题)。小新想知道刷完其中的题目,自己的水平最大能达到多少?最快需要多久才能达到最高的水平?
输入
测试有多组样例,每组样例的第一行为三个数字g(1<=1000)、n(1<=n<=1000000)和z(1<=z<=100)。含义如题目所示。接下来一行包括n个正整数xi(1<=xi<=1000000),代表题目的难度。当g、n、z同时为0时,代表输入结束,此行不做处理。
输出
对于每组样例,输出一行"Case id: mg time"。其中id为样例编号,mg代表小新能达到的最高的水平,time代表小新达到最高水平所需要的最少的时间。
样例输入
3 4 20
6 25 40 60
5 3 2
10 6 1000
0 0 0
样例输出
Case 1: 60 65
Case 2: 6 3
解题思路
这一题其实只要读懂题意其实也不难。我们首先排一下序,因为做水题是不能提高水平的,还浪费时间,所以我们不做水题,把水题跳过。又因为只要满足x<=g+z的题都可以做,所以我们要一直找能提升水平最高的题做就行了(也可以用二分查找)。
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int s[1000010];
long long ans;
int main()
{
int g, z, n, j, t = 1;
while (scanf("%d%d%d", &g, &n, &z), g + n + z)
{
j = ans = 0;
for (int i = 0; i < n; i++)
scanf("%d", &s[i]);
sort(s, s + n);
while (j < n)
{
while (g >= s[j] && j < n)
j++;
while (g + z >= s[j] && j < n)
j++;
if (!j || g >= s[j - 1])
break;
ans += s[j - 1] - g + 2;
g = s[j - 1];
}
printf("Case %d: %d %lld\n", t++, g, ans);
}
return 0;
}