其他分享
首页 > 其他分享> > 杭电多校H . Lawn of the Dead(模拟)

杭电多校H . Lawn of the Dead(模拟)

作者:互联网

链接

题意:

\(n×m\) 的网格
有 \(k\)个不能走的点,坐标为\((x_i,y_i)\)
我们从\((1,1)\)点出发
一次移动可以向右 / 向下移动一格,最后走到不能走为止。
他有多少个格子是能够走得到的?

分析:

我们看题意可知,出了1这个点其他点如果能到,只能是他左边能到,或者上面能到,当然它本身一定能走,然后我们分析第一行,第一行的话,我们只能走到第一次遇到的那个点,因为后面的既没办法从左边走过来,又没办法从上面走过来,所以第一行可走的是\((1--(y_1-1))\),如果第一行没有点那么更简单,第一行都能走,下面的我们利用上面这个状态。

我们先将当前行可以从左边过来的小区间都搜出来,然后如果上面可以过来肯定下面这个区间的一部分就能过来,
假设上一行能到的区间是\((l_1,r_1)\),当前行从左边可用的区间是\((l_2,r_2)\),那么当前行可走的区间是\((max(l_1,l_2),r_2)\).

int n, m, k;
struct node
{
    int x, y;
} q[maxn];
bool cmp(node a, node b)
{
    if(a.x != b.x) return a.x < b.x;
    return a.y < b.y;
}
std::vector<pii> v[2], now;

void solve()
{
    n = read;
    m = read;
    k = read;
    for(int i = 1; i <= k; i++)
    {
        q[i].x = read;
        q[i].y = read;
    }
    sort(q + 1, q + 1 + k, cmp);

    int top = 1;
    int flag = 0;
    ll ans = 0;
    v[flag].clear();
    v[flag ^ 1].clear();

    v[flag].push_back({1, 1});
    for(int i = 1; i <= n; i++)
    {
        now.clear();
        if(q[top].x == i) /// find 行
        {
            int front = 1;
            while(top <= k && q[top].x == i) ///当前行的
            {
                if(front <= q[top].y - 1)
                {
                    now.push_back({front, q[top].y - 1});
                }
                front = q[top].y + 1; ///右移
                top++;
            }
            if(front <= m) now.push_back({front, m});
        }
        else
        {
            now.push_back({1, m});
        }

        int num1 = v[flag].size();
        int num2 = now.size();
        int tmp = 0;
        for(int i = 0; i < num2; i++)
        {
            while(tmp < num1 && v[flag][tmp].y < now[i].x) tmp++;
            if(tmp == num1) break;
            int l = max(v[flag][tmp].x, now[i].x);
            int r1 = min(v[flag][tmp].y, now[i].y);
            int r = now[i].y;
            if(r1 >= l)
            {
                v[flag ^ 1].push_back({l, r});
                ans += (r - l + 1);
            }

        }
        v[flag].clear();
        flag ^= 1;
    }
    cout << ans << endl;
}

标签:node,杭电多校,Lawn,第一行,int,Dead,read,flag,区间
来源: https://www.cnblogs.com/KingZhang/p/15083986.html