P9815 wbyblD

首先我们直接模拟 

x 点加上数据特判可以得到 
60



60pts。
观察发现,

x 点在移动的过程中会在一些点之间不停的移动,直到把 



i

  或 



i

  消耗完了之后才会继续移动,我们完全加速这个过程。
继续发现,

x 点在向右移动的过程中如果遇到一个 


>
0

i

 >0,那它就会给 



i

  减一后往回走,然后再遇到一个 


>
0

i

 >0,继续减一往回走。
拿一支笔画一下,我们会发现如果遇到一个 


>
0

i

 >0,那他前面的 



i

  之和就会被这个 



i

  消耗掉 



i

 ,如果不够消耗的(即减去 



i

  后小于 
0
0),那 

x 就会跑回 
0
0,否则就会被消耗掉 



i

  后继续前进。
至此我们有一个明确的思路,维护一个前面还没被消耗光的 



i

  之和 



cnt,每走到一个新的 



i

 ,就判断一下 



cnt 是否大于等于这个 



i

 ,如果大于,则将 



cnt 减去 



i

 ,继续前进,否则输出 
0
0。
如果过程中没有输出 
0
0,则证明 

x 走到了终点,输出 

+
1
n+1。
代码如下:
#include
#define int long long
using namespace std;
int a[1000005], b[1000005], n;
signed main() {
    int T;
    cin >> T;
    if (T == 10) while (T -- ) puts("0");
    else {
        while (T -- ) {
            scanf("%lld", &n);
            for (int i = 1; i <= n; ++ i) scanf("%lld%lld", a + i, b + i);
            a[0] = b[0] = a[n + 1] = b[n + 1] = 0;
//            int x = 0, y = 1;
//            while (!(x == 0 && y == -1) && !(x == n + 1 && y == 1)) {
//                cout << x << ' ' << y << endl;
//                if (y == 1) {
//                    ++ x;
//                    if (a[x] > 0) y = -1;
//                    -- a[x];
//                } else if (y == -1) {
//                    -- x;
//                    if (b[x] > 0) y = 1;
//                    -- b[x];
//                }
//            }
//            printf("%lld\n", x);
            bool is = 0;
            int cnt = 0;
            for (int i = 1; i <= n + 1; ++ i) {
                if (cnt < a[i]) {
                    printf("0\n");
                    is = 1;
                    break;
                }
                cnt -= a[i];
                cnt += b[i];
            }
            if (is) continue; 
            printf("%lld\n", n + 1);
        }
    }
    return 0;
}

你可能感兴趣的:(算法,图论)