HDU -- 5037 Frog (贪心)(2014北京网络赛)

来源:互联网 发布:域名邮箱反查询 编辑:程序博客网 时间:2024/04/25 20:49

一只青蛙要过河,河面上现在有n块石头,青蛙每次最长跳L,河宽m。你可以随意在河里加石头,让青蛙跳过河的步数最多。

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

这种题比赛的时候居然没过QAQ!!!!!

在现有的石头上跳到不能跳为止,跳到一个点,记录它前一个点的位置from.(现在处在的点是cur)

跳到从from不能跳到的最近的为止,然后cur变成from,cur变成刚刚跳到的点,然后一直向下跳,直到可以碰到原有的石头。

直接模拟这样做一定会超时=。=

可以发现,每次都是跳到from+L+1的位置。

我们以跳两步为单位,每次就是将from和cur都向前平移了L+1。

。。。还有一些细节处理,看代码。

最后就是。。千万别忘了sort!QAQ。。。

#include <map>#include <set>#include <cmath>#include <queue>#include <stack>#include <cstdio>#include <string>#include <vector>#include <cstring>#include <iostream>#include <algorithm>using namespace std;typedef double DB;typedef long long ll;typedef unsigned long long ull;typedef pair<int, int> PII;#define pb push_back#define MP make_pair#define lson l, m, rt << 1#define rson m + 1, r, rt << 1 | 1const DB eps = 1e-8;const int inf = 0x3f3f3f3f;const int mod = 10000007;const int maxn = 200000 + 10;int T, n, m, l, a[maxn], from;int now;bool ok;int cal(int i, int j){    ok = true;    int cur, tmp;    int ret = 0;    cur = from + l + 1;///跳到from跳不到的最近的位置    ret = 1;    from = a[i];    int k = cur - from;    int cnt = (a[j] - cur) / (l + 1);    ret += cnt * 2;    cur = cnt * (l + 1) + cur;    from = cur - k;    if(from + l >= a[j]){///如果这时从from就能跳到a[j]        cur = a[j];    }else{        from = cur;        cur = a[j];        ret++;    }    tmp = from;    if(j + 1 <= n + 1 && a[j + 1] - tmp <= l){///如果可以跳到更后边的点,就向后跳        now = j + 1;        ok = false;        while(a[now] - tmp <= l) now++;        now -= 2;    }    return ret;}int main(){    //freopen("in.txt", "r", stdin);    scanf("%d", &T);    for(int cas=1; cas<=T; cas++){        scanf("%d%d%d", &n, &m, &l);        a[0] = 0; a[n + 1] = m;        for(int i=1; i<=n; i++)            scanf("%d", &a[i]);        sort(a, a + n + 2);        printf("Case #%d: ", cas);        if(l == 1) {printf("%d\n", m); continue;}        int ans = 0;        from = -l;        for(int i=0; i<=n; i++){            int j = i + 1;            if(a[j] - a[i] <= l){                while(a[j] - a[i] <= l) j++;                ans++;                from = a[i];                i = j - 2;            }else{                ans += cal(i, j);                if(!ok) i = now;            }        }        printf("%d\n", ans);    }    return 0;}


0 0