P1884 [USACO12FEB]过度种植(银)
毒瘤数据!!!
我能说我被这道题卡了三四天吗。。。
这道题就是给你二维坐标,让你求总矩形面积,覆盖的面积只算一次。
本来想用二维的线段覆盖,结果因为chen_zhe大佬的数据加强过不了了。
所以只能够使用矩形切割算法。
其实理解了也简单,都不用说,自己看代码就懂了。
不过注意的是:这道题要用long long!!!!!!
代码:
#include<cstdio>
const int maxn = 1005;
struct Nodes
{
long long l, r, u, d;
} s[maxn];
int n;
long long ans;
void work(Nodes now, int p)
{
if(now.l > now.r || now.d > now.u) return;//不存在这样的矩形
while(p && (s[p].r <= now.l || now.r <= s[p].l || s[p].u <= now.d || now.u <= s[p].d)) p--;//与前面的矩形需要不冲突
if(p == 0)//不冲突的话可以计算面积
{
ans += (now.r - now.l) * (now.u - now.d);
return;
}
//否则我们需要切割矩形,直到矩形不冲突为止
if(now.l < s[p].l)
{
work((Nodes){now.l, s[p].l, now.u, now.d}, p - 1);
now.l = s[p].l;
}
if(s[p].r < now.r)
{
work((Nodes){s[p].r, now.r, now.u, now.d}, p - 1);
now.r = s[p].r;
}
if(s[p].u < now.u)
{
work((Nodes){now.l, now.r, now.u, s[p].u}, p - 1);
now.u = s[p].u;
}
if(now.d < s[p].d)
{
work((Nodes){now.l, now.r, s[p].d, now.d}, p - 1);
now.d = s[p].d;
}
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%lld%lld%lld%lld", &s[i].l, &s[i].u, &s[i].r, &s[i].d);
for(int i = 1; i <= n; i++) work(s[i], i - 1);
printf("%lld\n", ans);
return 0;
}