离散化:将无限空间的有限个体映射到有限的空间上,做到逻辑上的有限和有序,避免重复。


学习矩形切割就不得不认识线段切割。进而和离散化扯上了关系。


关于线段切割:


矩形切割-面积求并_ios


设线段ab和cd有交集:k1k2




矩形切割-面积求并_ios_02



当a<k1,ab分解(切割)成ak1


矩形切割-面积求并_ios_03



当b>k2,ab分解(切割)成k2b



相关题目:


VIJOS 1165 火烧赤壁


​https://vijos.org/p/1165​


大意:统计线段的覆盖长度


分析:改变有重叠区的线段的终点,然后相加即可。


例如:


矩形切割-面积求并_i++_04


计算过程:


L=0


L=L+2=2


9-->11


L=L+11-2=11


#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
struct edge{
int x1,x2;
}eg[20005];
int cmp(edge a,edge b){
return a.x1<b.x1||(a.x1==b.x1&&a.x2<b.x2);
}
int main()
{
//freopen("cin.txt","r",stdin);
int n;
while(cin>>n){
for(int i=0;i<n;i++){
scanf("%d%d",&eg[i].x1,&eg[i].x2);
}
sort(eg,eg+n,cmp);
int L=0;
int s=eg[0].x1,e=eg[0].x2;
for(int i=1;i<n;i++){
if(eg[i].x1<e&&eg[i].x2>e) e=eg[i].x2;
else if(eg[i].x1>=e){
L=L+e-s;
s=eg[i].x1;
e=eg[i].x2;
}
}
if(n>0)L=L+e-s;
printf("%d\n",L);
}
return 0;
}



矩形切割:


X方向和Y方向分别进行分割。


矩形切割-面积求并_ios_05


X:


x1<x3,S1矩形 -> (x1,y1)-(x3,y2)


x2>x4,S1矩形 -> (x4,y1)-(x2,y2)


矩形切割-面积求并_矩形_06


Y:


y1<y3,S1矩形 -> (x1,y1)-(x2,y3)


y2>y4,S2矩形 -> (x1,y3)-(x2,y2)



POJ 3695


​http://poj.org/problem?id=3695​

给出不多于20个矩形,M个询问,每个询问问r个矩形面积的并。



#include <iostream>
#include <cstdio>
using namespace std;
struct node{
int x1,y1,x2,y2;
int s;
}rec[25];
int a[25];
int r;
void cover(int x1,int y1,int x2,int y2,int k){
while(k<r&&(x1>=rec[a[k]].x2||x2<=rec[a[k]].x1||y1>=rec[a[k]].y2||y2<=rec[a[k]].y1)) k++;
if(k>=r) {
rec[a[k-1]].s+=(x2-x1)*(y2-y1);
return ;
}
if(x1<rec[a[k]].x1){
cover(x1,y1,rec[a[k]].x1,y2,k+1);
x1=rec[a[k]].x1;
}
if(x2>rec[a[k]].x2){
cover(rec[a[k]].x2,y1,x2,y2,k+1);
x2=rec[a[k]].x2;
}
if(y1<rec[a[k]].y1){
cover(x1,y1,x2,rec[a[k]].y1,k+1);
y1=rec[a[k]].y1;
}
if(y2>rec[a[k]].y2){
cover(x1,rec[a[k]].y2,x2,y2,k+1);
y2=rec[a[k]].y2;
}
}
int main(){
//freopen("cin.txt","r",stdin);
int n,m;
int t=0;
while(cin>>n>>m&&(n+m)){
for(int i=0;i<n;i++){
scanf("%d%d%d%d",&rec[i].x1,&rec[i].y1,&rec[i].x2,&rec[i].y2);
}
printf("Case %d:\n",++t);
for(int k=1;k<=m;k++){
scanf("%d",&r);
for(int i=0;i<r;i++) {
scanf("%d",&a[i]);
a[i]--;
}
for(int i=0;i<n;i++){
rec[i].s=0;
}
for(int i=r-1;i>=0;i--){
cover(rec[a[i]].x1,rec[a[i]].y1,rec[a[i]].x2,rec[a[i]].y2,i+1);
}
int ans=0;
for(int i=0;i<r;i++) ans=ans+rec[a[i]].s;
printf("Query %d: %d\n",k,ans);
}
puts("");
}
return 0;
}