洛谷P1884 [USACO12FEB]Overplanting S (矩形切割)

一种矩形切割的做法:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn=1005;
 5 struct node{//矩形的结构体 
 6     LL x1,y1,x2,y2;
 7 }a[maxn];
 8 int n,cnt=0;
 9 
10 void Cut(LL id,LL x1,LL y1,LL x2,LL y2){//矩形切割 
11     LL k1,k2,k3,k4;
12     k1=max(a[id].x1,x1);
13     k2=min(a[id].x2,x2);
14     k3=min(a[id].y1,y1);
15     k4=max(a[id].y2,y2);
16     if(a[id].x1<k1) a[++cnt]=(node){a[id].x1,a[id].y1,k1,a[id].y2};
17     if(a[id].x2>k2) a[++cnt]=(node){k2,a[id].y1,a[id].x2,a[id].y2};
18     if(a[id].y1>k3) a[++cnt]=(node){k1,a[id].y1,k2,k3};
19     if(a[id].y2<k4) a[++cnt]=(node){k1,k4,k2,a[id].y2};
20 }
21 
22 int read(){
23     int x=0,f=1;
24     char c=getchar();
25     while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
26     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
27     return x*f;
28 }
29 
30 int main(){
31     n=read();
32     LL x1,y1,x2,y2;
33     x1=read();y1=read();x2=read();y2=read();
34     a[++cnt]=(node){x1,y1,x2,y2};//先加入一个矩形 
35     for(int i=2;i<=n;i++){
36         x1=read();y1=read();x2=read();y2=read();
37         for(int j=1;j<=cnt;j++){
38             if(a[j].x1>=x2||a[j].x2<=x1||a[j].y1<=y2||a[j].y2>=y1)continue;
39             Cut(j,x1,y1,x2,y2);//若相交,用当前矩形去切割 
40             a[j--]=a[cnt--];//删除原矩形,用最后一个矩形来覆盖它 
41         }
42         a[++cnt]=(node){x1,y1,x2,y2};//加入新矩形 
43     }
44     LL ans=0;
45     for(int i=1;i<=cnt;i++)
46         ans+=(a[i].x2-a[i].x1)*(a[i].y1-a[i].y2);
47     cout<<ans;
48 }

好像更普遍的解法是扫描线+线段树,这里先留一个坑,以后再来补上这种做法。

posted @ 2022-04-16 16:32  YHXo  阅读(90)  评论(0编辑  收藏  举报