hdu5037 Frog (贪心)

http://acm.hdu.edu.cn/showproblem.php?pid=5037

网络赛 北京 比较难的题

Frog

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 99    Accepted Submission(s): 11

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

Source

2014 ACM/ICPC Asia Regional Beijing Online

Recommend

hujie   |   We have carefully selected several similar problems for you:  5041 5040 5039 5038 5036

题意:

有个青蛙在数轴上跳,要从0跳到M,每次能跳0~L,数轴是个水面,只能跳到石头上。给出若干已有石头,可以在任意位置添加石头。要让青蛙能跳到终点,并且跳的步数最大。

题解:

贪心狂跳。

先给石子排个序,添加一个石子m代表终点。

设当前青蛙在now处,上一步在pre处(初始化负无穷)。

先在已有石子上狂跳,每次跳到能跳的最远的那个。

当不能继续跳的时候(下一个石子距离过远),就加石子。

加石子要加在max(now+1,pre+l+1)处,也就是pre刚好不能跳到的,now能跳到的最近的那一个。

然后重复,如果能跳到已有石头就跳,跳不到就加石头。

简直贪,这样就能得到正确答案!

不过这样有可能要跳太多次,会TLE,所以当两个石头距离过远的时候,可以特殊处理一下新建好多石头跳好多步。

可以发现连续新建两个石头跳两步的话,肯定是到now+l+1,于是可以直接跳若干个(l+1)步。

(简直比青蛙棋还难,我怕了)

代码:

 1 //#pragma comment(linker, "/STACK:102400000,102400000")
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<cmath>
 8 #include<map>
 9 #include<set>
10 #include<stack>
11 #include<queue>
12 using namespace std;
13 #define ll long long
14 #define usll unsigned ll
15 #define mz(array) memset(array, 0, sizeof(array))
16 #define mf1(array) memset(array, -1, sizeof(array))
17 #define minf(array) memset(array, 0x3f, sizeof(array))
18 #define REP(i,n) for(i=0;i<(n);i++)
19 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
20 #define RD(x) scanf("%d",&x)
21 #define RD2(x,y) scanf("%d%d",&x,&y)
22 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
23 #define WN(x) printf("%d\n",x);
24 #define RE  freopen("D.in","r",stdin)
25 #define WE  freopen("huzhi.txt","w",stdout)
26 #define mp make_pair
27 #define pb push_back
28 const double pi=acos(-1.0);
29 const double eps=1e-10;
30
31 const int maxn=222222;
32
33 int n,m,l;
34 int a[maxn];
35
36 int farm() {
37     int now=0,pre=-maxn;
38     int i=1;
39     int ans=0;
40     a[n+1]=m;
41     sort(a+1,a+n+2);
42     a[n+2]=m+l+1;
43     while(now<m) {
44         while(a[i]<=now+l)i++;
45         //printf("i=%d\n, a[i]=%d, a[i-1]=%d\n",i,a[i],a[i-1]);
46         if(a[i-1]>now) {
47             pre=now;
48             now=a[i-1];
49             ans++;
50         } else {
51             int w=(a[i]-now)/(l+1)-1;
52             if(w>0) {
53                 int t=max(now+1,pre+l+1);
54                 pre=t+(w-1)*(l+1);
55                 now+=w*(l+1);
56                 ans+=w*2;
57             } else {
58                 int t=now;
59                 now=max(now+1,pre+l+1);
60                 pre=t;
61                 ans++;
62             }
63         }
64         //printf("%d %d %d\n",now,pre,ans);
65     }
66     return ans;
67 }
68
69 int main() {
70     int T,cas=1;
71     int i;
72     RD(T);
73     while(T--) {
74         RD3(n,m,l);
75         FOR(i,1,n)scanf("%d",&a[i]);
76         printf("Case #%d: %d\n",cas++,farm());
77     }
78     return 0;
79 }

时间: 2025-01-17 01:56:14

hdu5037 Frog (贪心)的相关文章

hdu5037 Frog --- 贪心

有一只萌萌哒小青蛙要过河,过河路线可以看成一个数轴,起点为0,终点为m. 小青蛙不会游泳,只能跳到数轴上一些有树桩的点直到跳过河,小青蛙一次能跳的最大距离是L. 小青蛙想用尽量少的步数过河,而你想让他跳尽量多的次数. 现在你可以向数轴上一些位置添加树桩,使青蛙顺利过河,并达到你的目的.青蛙是以最佳策略过河的. 纠结的题意.. 首先分析一下青蛙的最佳策略,一定是每次跳的越远越好, 假设a<b,那么通过a能到达的点,b一定能到达,所以当有多个点可以选择时,一定跳到最远的那个. 既然青蛙每次尽量跳的远

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 4004 The Frog&#39;s Games(基本算法-贪心,搜索-二分)

The Frog's Games Problem Description The annual Games in frogs' kingdom started again. The most famous game is the Ironfrog Triathlon. One test in the Ironfrog Triathlon is jumping. This project requires the frog athletes to jump over the river. The

HDU 4004 The Frog&#39;s Games 二分 贪心

戳这里:HDU 4004 //思路:二分经典入门题...贪心判方案是否可行 1 #include "bits/stdc++.h" 2 using namespace std; 3 int L, n, m; 4 int pos[500010], dis[500010]; 5 6 bool Cant(int Dis_Jump) 7 { 8 int i, Dis_Sum = 0, Count = 0; 9 for(i = 1; i <= n + 1; ++i) { 10 if(dis[

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.

2014北京网络预选赛1006(贪心)HDU5037

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

hdoj 5037 Frog 【万恶的贪心】

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