题目描述
给出n个矩形,求这些矩形面积的并。
输入格式
输入包含多组测试数据;
每组数据的第一行包含一个整数n(1<=n<=1000),表示矩形的个数。
接下来n行,每行四个数(不一定是整数)x1,y1,x2,y2 (0<=x1最后一行以0作为文件的结束。
输出格式
对于每组测试数据,输出两行;
第一行是“Test case #k”,k是组数 (开始为1);
第二行为“Total explored area: a”,a是所有矩形面积并,保留到小数点后两位。
最后每组数据结束后输出一空行。
样例数据
样例输入
2
10 10 20 20
15 15 25 25.5
0
样例输出
Test case #1
Total explored area: 180.00
题目分析
矩形切割模板题
写了一个二维的矩形切割
又用通用维度矩形切割做了一遍,看看就行了
源代码
二维
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
inline const int Get_Int() {
int n=0,bj=1;
char x=getchar();
while(x<'0'||x>'9') {
if(x=='-')bj=-1;
x=getchar();
}
while(x>='0'&&x<='9') {
n=n*10+x-'0';
x=getchar();
}
return n*bj;
}
struct Square {
double x1,x2,y1,y2;
Square() {}
Square(double lx,double ly,double rx,double ry):x1(lx),y1(ly),x2(rx),y2(ry) {}
} ;
struct Cut_Square {
Square a[100005];
int sum;
int init() {
sum=0;
}
bool if_intersect(Square a,Square b) {
if(a.x1>=b.x2||a.y1>=b.y2||a.x2<=b.x1||a.y2<=b.y1)return false;
else return true;
}
void add(double x1,double y1,double x2,double y2) {
a[++sum]=Square(x1,y1,x2,y2);
}
void del(int index) {
a[index]=a[sum];
sum--;
}
void Xway_cut(int index,double x1,double y1,double x2,double y2) {
double k1=max(x1,a[index].x1);
double k2=min(x2,a[index].x2);
if(a[index].x1<k1)add(a[index].x1,a[index].y1,k1,a[index].y2);
if(k2<a[index].x2)add(k2,a[index].y1,a[index].x2,a[index].y2);
Yway_cut(index,k1,y1,k2,y2);
}
void Yway_cut(int index,double x1,double y1,double x2,double y2) {
double k1=max(y1,a[index].y1);
double k2=min(y2,a[index].y2);
if(a[index].y1<k1)add(x1,a[index].y1,x2,k1);
if(k2<a[index].y2)add(x1,k2,x2,a[index].y2);
}
};
Cut_Square s;
int n,cnt=0;
double ans;
int main() {
ios::sync_with_stdio(false);
while(true) {
cin>>n;
if(n==0)break;
s.init();
cnt++;
ans=0;
for(int i=1; i<=n; i++) {
double x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
Square b(x1,y1,x2,y2);
for(int j=1; j<=s.sum; j++) {
if(!s.if_intersect(s.a[j],b))continue; //不相交
s.Xway_cut(j,x1,y1,x2,y2);
s.del(j);
j--; //删除完矩形移动了最后一个矩形,若j不-1可能导致原矩形未切割
}
s.add(x1,y1,x2,y2);
}
for(int i=1; i<=s.sum; i++)ans+=(s.a[i].x2-s.a[i].x1)*(s.a[i].y2-s.a[i].y1);
printf("Test case #%d\nTotal explored area: %0.2lf\n\n",cnt,ans);
}
return 0;
}
通用
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
inline const int Get_Int() {
int num=0,bj=1;
char x=getchar();
while(x<'0'||x>'9') {
if(x=='-')bj=-1;
x=getchar();
}
while(x>='0'&&x<='9') {
num=num*10+x-'0';
x=getchar();
}
return num*bj;
}
const int maxn=2;
struct Cube {
double left[maxn],right[maxn];
} ;
struct Universal_Cut {
Cube a[10005];
int sum;
int init() {
sum=0;
}
bool if_intersect(Cube a,Cube b) {
for(int i=0; i<maxn; i++)
if(a.left[i]>=b.right[i]||a.right[i]<=b.left[i])return false;
return true;
}
void add(double x[maxn],double y[maxn]) {
sum++;
for(int i=0; i<maxn; i++) {
a[sum].left[i]=x[i];
a[sum].right[i]=y[i];
}
}
void del(int index) {
a[index]=a[sum];
sum--;
}
void cut(Cube a,Cube b,int dimension) { //返回交集
if(dimension==maxn)return;
double k1=max(a.left[dimension],b.left[dimension]);
double k2=min(a.right[dimension],b.right[dimension]);
if(a.left[dimension]<k1) {
Cube tmp=a;
tmp.right[dimension]=k1;
add(tmp.left,tmp.right);
}
if(k2<a.right[dimension]) {
Cube tmp=a;
tmp.left[dimension]=k2;
add(tmp.left,tmp.right);
}
a.left[dimension]=k1;
a.right[dimension]=k2;
cut(a,b,dimension+1);
}
};
Universal_Cut c;
int n,cnt=0;
double Bleft[maxn],Bright[maxn],ans=0;
int main() {
ios::sync_with_stdio(false);
while(true) {
cin>>n;
if(n==0)break;
ans=0;
c.init();
for(int i=1; i<=n; i++) {
cin>>Bleft[0]>>Bleft[1]>>Bright[0]>>Bright[1];
Cube b;
for(int i=0; i<maxn; i++) {
b.left[i]=Bleft[i];
b.right[i]=Bright[i];
}
for(int j=1; j<=c.sum; j++) {
if(!c.if_intersect(c.a[j],b))continue;
c.cut(c.a[j],b,0);
c.del(j);
j--;
}
c.add(Bleft,Bright);
}
for(int i=1; i<=c.sum; i++) {
int tmp=1;
for(int j=0; j<maxn; j++)
tmp*=c.a[i].right[j]-c.a[i].left[j];
ans+=tmp;
}
printf("Test case #%d\nTotal explored area: %0.2lf\n\n",++cnt,ans);
}
return 0;
}