hdu 5037 Frog

这题我都不想吐槽了,北京区域赛的资格没拿到就怪我这题的bug一直没找出来

看网上别人都是用贪心做的,我觉得我是分情况讨论的。

 

题意:

青蛙在x轴坐标上跳,青蛙初始坐标为0,终点为M,每次青蛙最远跳l个单位且青蛙必须跳到有石头的坐标。 已存在N个石头,石头坐标为a1,a2,..an, 现在你可以放任意多个石头在任意坐标上, 青蛙会尽快跳到终点,求青蛙跳到终点最多需要多少步 

 

首先,因为我们要使得青蛙跳的步数尽可能多,所以我们会尽量使得青蛙每两步跳的距离为l+1。(这个模拟一下就可以得到), 但青蛙想尽可能跳少一点,所以青蛙每次都会

跳到能跳的最远距离。 所以我们需记录青蛙上一步跳的距离才能算出这步的最优距离

 

例如:

青蛙从0跳到8,每次最远跳4,第一步青蛙跳1, 第二步跳到5,第三步跳到8

因为青蛙每两步跳l+1 最优 , 所以我们可以对区间[L,R] 先预处理出 ans+= 2*(R-L)/(L+1) ,然后对(R-L)%(L+1)讨论 

设第一个石头坐标为0,

例如

设记录值为t

1 8 4

1

青蛙先跳一步到坐标1, 记录上一步的距离为1,然后对【1,8】区间计算时,青蛙会用两步来跳l+1距离得 ans+= 2,  青蛙到达6, 剩下的距离即余数yu = (8-1)%5= 2

因为记录的值为1,所以青蛙第三步是从5跳到6,但是青蛙,从5已经可以跳到8了, 所以这是对剩下的距离不处理,且更新记录值为3  即情况 t+yu<= l

1 10 4

2

同上可算得对【1,10】区间计算时记录值为2,yu= (9-2)%5= 2,因为记录的值是2,所以青蛙第三步是从5跳到7,但是青蛙从5不能跳到10,所以青蛙必须跳到7之后才能跳过或跳到该石头 即情况t+yu> l

 

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
using namespace std;
#define maxn 222222

int a[maxn];

int main()
{
    int T;
   	scanf("%d",&T);
    for(int C= 1; C<= T; C++)
    {
        int n, m ,l;
        scanf("%d %d %d",&n,&m,&l);
        for(int i= 1; i<= n; i++)
            scanf("%d",&a[i]);
        sort(a+1, a+n+1);
        a[0]= 0;
        a[n+1]= m;
        a[n+2]= INT_MAX;
        int ans= 0, L= 0, R= a[1], time= l, i= 0;
        while(i<= n)
        {
            if(L> a[n])
                break;
            int xx= (R- L)/(l+1);
            ans+= xx*2;
            int yu= (R- L)%(l+1);
            int LL;
            if(yu + time> l)
                ans++, LL= L+ (l+1)*xx;
            else if(yu+ time <= l)
                LL= L + (l+1)*xx- time;
            for(int j= i; j<= n+2; j++)
                if(a[j]- LL<= l)
                {
                    L= a[j];
                    R= a[j+1];
                    time= a[j]- LL;
                    i= j;
                }   //看那个石头是青蛙跳不过去的,跳的过去的石头都不考虑 
            	else
            		break;  // 这里忘记break TLE了十多次 
        }
        printf("Case #%d: %d\n",C,ans);    
    }
    return 0;
}


 

你可能感兴趣的:(hdu 5037 Frog)