hdu 5037 Frog (贪心)

Frog

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)

Total Submission(s): 789    Accepted Submission(s): 198

Problem Description

Once upon a time, there is a little frog called Matt. One day, he came to a river.

The river could be considered as an axis.Matt is standing on the left bank now (at position 0). He wants to cross the river, reach the right bank (at position M). But Matt could only jump for at most L units, for example from 0 to L.

As the God of Nature, you must save this poor frog.There are N rocks lying in the river initially. The size of the rock is negligible. So it can be indicated by a point in the axis. Matt can jump to or from a rock as well as the bank.

You don‘t want to make the things that easy. So you will put some new rocks into the river such that Matt could jump over the river in maximal steps.And you don‘t care the number of rocks you add since you are the God.

Note that Matt is so clever that he always choose the optimal way after you put down all the rocks.

Input

The first line contains only one integer T, which indicates the number of test cases.

For each test case, the first line contains N, M, L (0<=N<=2*10^5,1<=M<=10^9, 1<=L<=10^9).

And in the following N lines, each line contains one integer within (0, M) indicating the position of rock.

Output

For each test case, just output one line “Case #x: y", where x is the case number (starting from 1) and y is the maximal number of steps Matt should jump.

Sample Input

2
1 10 5
5
2 10 3
3
6

Sample Output

Case #1: 2
Case #2: 4

贪心思想:每次总是尽量让青蛙走最近的石头,需要记录当前和上一个青蛙跳的石头位置。

1、如果可以跳到下一个石头能到达,就跳到最远的那个;

2、否则,就需要添加加石头,石头加在max(now+1,pre+l+1)处,也就是pre刚好不能跳到的,now能跳到的最近的那一个。使前一个和后一个距离总为L+1,得到最优解。

#include"stdio.h"
#include"math.h"
#include"string.h"
#include"iostream"
#include"algorithm"
using namespace std;
#define N 200005
const int inf=(int)1e10;
int a[N];
int max(int a,int b)
{
    return a>b?a:b;
}
int main ()
{
    int n,i,cnt=1,T,m,l,ans;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&m,&l);
        for(i=1;i<=n;i++)
            scanf("%d",&a[i]);
        a[0]=0;
        a[n+1]=m;
        sort(a,a+n+2);
        n+=2;
        int pre,now;
        pre=-inf;
        now=0;
        ans=0;
        i=1;
        while(now<m)
        {
            while(a[i]-now<=l&&i<n)
                i++;
            if(a[i-1]>now&&a[i-1]<=now+l)
            {
                pre=now;
                now=a[i-1];
                ans++;
            }
            else
            {
                int w=(a[i]-now)/(l+1)-1;
                if(w>0)
                {
                    int t=max(now+1,pre+l+1);
                    pre=t+(w-1)*(l+1);
                    now+=w*(l+1);
                    ans+=w*2;
                }
                else
                {
                    int t=max(now+1,pre+l+1);
                    pre=now;
                    now=t;
                    ans++;
                }
            }
        }
        printf("Case #%d: %d\n",cnt++,ans);
    }
    return 0;
}
时间: 2024-08-07 08:40:19

hdu 5037 Frog (贪心)的相关文章

HDU 5037 FROG (贪心)

Problem Description Once upon a time, there is a little frog called Matt. One day, he came to a river. The river could be considered as an axis.Matt is standing on the left bank now (at position 0). He wants to cross the river, reach the right bank (

hdu 5037 Frog 贪心 dp

哎,注意细节啊,,,,,,,思维的严密性..... 11699193 2014-09-22 08:46:42 Accepted 5037 796MS 1864K 2204 B G++ czy Frog Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 454    Accepted Submission(s): 96 Problem

HDU 5037 FROG 贪心 2014北京网络赛F

题目链接:点击打开链接 题意:有一条小河长为M的小河,可以看作一维轴,小河里存在N个石头,有一个每次能跳L米的小青蛙,随意添加石头保证青蛙能从头跳到尾的,问青蛙使用最优策略跳到对岸最多需要多少次. 思路:不妨假设青蛙每个石头都要经过一次,用step表示青蛙上一次跳的步长,每跳一次对目前点到下一点的距离和step的和与L做比较,如果小与,证明青蛙可以一次跳到这,更新step和青蛙位置,cnt保持不变,若大于,证明青蛙至少需要再跳一次,若lenth<=l,则直接跳,更新step=lenth,cnt+

hdu 5037 Frog(高效)

题目链接:hdu 5037 Frog 题目大意:给定N,M,L,表示有一只条宽为M的河,青蛙要从0跳到M,青蛙的最大跳跃能力为L,现在已经存在了N块石头,现在要放任意数量的石头,使得说青蛙需要用最多的步数跳到M. 解题思路:维护两个指针,pos表示青蛙当前的位置,mv表示青蛙在前一个位置能跳到的最远位置.然后周期L+1的长度可以让青蛙需要跳两次.但注意每一段长度的最后一个周期需要特判,因为有可能只需要一步. #include <cstdio> #include <cstring>

hdu 5037 Frog(贪心)

分析:贪心吧,让三个石头第一个和第三个距离为L+1,并让每次跳的点尽量小. 石头是可能无序的,比赛是实在没发现,就加了个排序过了,哎... 和代码一起讲做法吧,假设情况1 :上一步k加这一步余数x大于L,则最后剩余部分需要单独跳:情况2:上一步k加这一步余数x小于等于L,最后剩余部分可以并进上一步,即k+x. 画了一张图: 代码: #include<iostream> #include<queue> #include<map> #include<cstdio>

hdu 5037 Frog

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 2040    Accepted Submission(s): 616 Problem Description Once upon a time, there is a little frog called Matt. One day, he came to a river. The

hdu 5037 Frog(北京网络赛)

Frog                                                              Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 1086    Accepted Submission(s): 285 Problem Description Once upon a time, the

hdoj 5037 Frog 【万恶的贪心】

题目:hdoj 5037 Frog 题意:一直聪明的青蛙,每次能条 l 的长度,河宽为m,喝中心有一些陆地,它会选择尽量少的次数跳,现在上帝可以任意往喝里面放陆地(视为点),让青蛙跳的次数最多,求最大次数? 分析:1:首先如果加入大于(l+1)的距离,那么上帝会给他分成(l+1)的段,因为我给他(l+1),它一下子跳不过去,必然中间还要一个点,让青蛙跳,这样肯定步数最大.(贪心策略) 2:贪心的时候以每一段剩余区间开始点作为贪心的开始点,假如它和后面区间的和大于等于(l+1)时,那么可以让它跳过

hdu 4869 Task(贪心)

题目链接:hdu 4869 Task 题目大意:有n台机器,m个任务,每个机器和任务都有有xi和yi,要求机器的xi,yi均大于等于任务的xi和yi才能执行任务.每台机器一天只能执行一个任务.要求完成的任务数尽量多,并且说金额尽量大.完成每个任务的金额为xi?500+yi?2 解题思路:贪心,mach[i][j]表示等级为i,时间为j的机器数量,task[i][j]表示等级为i,时间为j的机器数量.每次优先减少i,因为对应等级减少100,对应的金额代价也不会减少超过500(即时间减少1). 每次