1. 程式人生 > >ZZULI - 小新三連(二):小新在努力

ZZULI - 小新三連(二):小新在努力

題目連結: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;
}