[POI2017] Flappy Bird 题解

提交处(搬运过的位置):http://www.gdfzoj.com/oj/problem/469

题目


Problem Description
《飞扬的小鸟》是一款风靡的小游戏。在游戏中,小鸟一开始位于(0,0)处,它的目标是飞到横坐标为X的某个位置上。

每一秒,你可以选择点击屏幕,那么小鸟会从(x,y)飞到(x+1,y+1),或者不点击,那么小鸟会飞到(x+1,y-1)。

在游戏中还有n个障碍物,用三元组(x[i],a[i],b[i])描述,表示在直线x=x[i]上,y<=a[i]或者y>=b[i]的部分都是障碍物,碰到或者擦边都算游戏失败。

请求出小鸟从(0,0)飞到目的地最少需要点击多少次屏幕。

分析

首先,从起点飞到一个确定的点(n, m)需要的点击次数是固定的。
公式为 : 次数 = (x+y)/2;

然后,对于每一个列,我们可以从上一个已确定的列,得出当前列的可达范围。
顺便,当前高度和当前列数的奇偶性一定相同(显而易见)。
所以,从前一个上下界和当前的“柱子”还有奇偶性,可以实现递推。

代码

#include
#include
using namespace std;
int n, X, x, a, b, lx = 0, lmax = 0, lmin = 0;
int main() {
    scanf("%d%d", &n, &X);
    for(int i = 1; i <= n; i++) {
        scanf("%d%d%d", &x, &a, &b);
        lmax += x - lx;
        lmin -= x - lx;
        lmax = min(b-1, lmax);
        lmin = max(a+1, lmin);
        if(x & 1) lmax -= !(lmax & 1), lmin += !(lmin & 1);
        else lmax -= lmax & 1, lmin += lmin & 1;
        if(lmax <= a || lmin >= b || lmax < lmin) {
            printf("NIE\n");
            return 0;
        }
        lx = x;
    }
    printf("%d\n", (lmin+lx) / 2);
    return 0;
}

你可能感兴趣的:(作业)