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 | 1
using 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