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;
}
posted @ 2018-08-22 13:29  Garen-Wang  阅读(219)  评论(0编辑  收藏  举报