poj 2528 线段覆盖 求能看到的线段有几段 (线段切割) poj 3277 (矩形切割)

来源:互联网 发布:制作软件需要什么 编辑:程序博客网 时间:2024/06/02 23:22

poj  2528:

题意:

在一条直线上有几条线段按照输入顺序往上贴,问最后能看到的线段有几条。


解析:

线段树看不懂,学了一种解法,叫线段切割。

来自:http://blog.csdn.net/acdreamers/article/details/8777920。


代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int maxn = 10000 + 10;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);struct Node{    int lo, hi;    int length;} p[maxn];int n;void cover(int lo, int hi, int nxt, int now){    while (nxt < n && (hi < p[nxt].lo || p[nxt].hi < lo))        nxt++;    if (n <= nxt) //无交集    {        p[now].length += hi - lo + 1;        return;    }    if (lo < p[nxt].lo) //当前线段右边被覆盖        cover(lo, p[nxt].lo - 1, nxt + 1, now);    if (p[nxt].hi < hi) //当前线段左边被覆盖        cover(p[nxt].hi + 1, hi, nxt + 1, now);}int main(){#ifdef LOCAL    freopen("in.txt", "r", stdin);#endif // LOCAL    int ncase;    scanf("%d", &ncase);    while (ncase--)    {        int ans = 0;        memset(p, 0, sizeof(p));        scanf("%d", &n);        for (int i = 0; i < n; i++)        {            scanf("%d%d", &p[i].lo, &p[i].hi);        }        for (int i = n - 1; i >= 0; i--)        {            cover(p[i].lo, p[i].hi, i + 1, i);        }        for (int i = 0; i < n; i++)        {            if (p[i].length)            {                ans++;            }        }        printf("%d\n", ans);    }    return 0;}


poj 3277:

链接:

http://blog.csdn.net/acdreamers/article/details/8778520

0 0
原创粉丝点击