洛谷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 }
好像更普遍的解法是扫描线+线段树,这里先留一个坑,以后再来补上这种做法。