Previous related blog: http://blog.csdn.net/lllcfr/article/details/7567045
先判断是否重叠,然后切割.注意答案要求的是哪一部分.
1. 二维矩形 USACO 5-3-window
#include <algorithm>
#include <cstdio>
#include <fstream>
#include <iomanip>
#include <list>
#include <queue>
#include <sstream>
#include <string>
using namespace std;
struct Window {
char id;
int x1, x2, y1, y2;
Window(const char _id, const int _x1, const int _y1, const int _x2, const int _y2) {
id = _id;
x1 = min(_x1, _x2);
x2 = max(_x1, _x2);
y1 = min(_y1, _y2);
y2 = max(_y1, _y2);
}
};
int main() {
ifstream fin("window.in");
ofstream fout("window.out");
list<Window> lst;
string cmd;
char id, ch;
while (fin >> cmd) {
id = cmd[2];
if (cmd[0] == 'w') {
istringstream iss(cmd.substr(4));
int x1, x2, y1, y2;
iss >> x1 >> ch >> y1 >> ch >> x2 >> ch >> y2;
lst.push_front(Window(id, x1, y1, x2, y2));
}
else if (cmd[0] == 't') {
auto it = lst.begin();
while (it != lst.end() && it->id != id)
++it;
lst.push_front(*it);
lst.erase(it);
}
else if (cmd[0] == 'b') {
auto it = lst.begin();
while (it != lst.end() && it->id != id)
++it;
lst.push_back(*it);
lst.erase(it);
}
else if (cmd[0] == 'd') {
auto it = lst.begin();
while (it != lst.end() && it->id != id)
++it;
lst.erase(it);
}
else if (cmd[0] == 's') {
auto it = lst.begin();
while (it != lst.end() && it->id != id)
++it;
double tot = (it->x2 - it->x1) * (it->y2 - it->y1);
queue<Window> q;
q.push(*it);
for (auto jt = lst.begin(); jt != it; ++jt) {
int n = q.size();
while (n--) {
Window w = q.front();
q.pop();
if (max(w.x1, jt->x1) >= min(w.x2, jt->x2) || max(w.y1, jt->y1) >= min(w.y2, jt->y2)) {
q.push(w);
continue;
}
if (jt->x1 > w.x1) {
q.push(Window(0, w.x1, w.y1, jt->x1, w.y2));
w.x1 = jt->x1;
}
if (jt->x2 < w.x2) {
q.push(Window(0, jt->x2, w.y1, w.x2, w.y2));
w.x2 = jt->x2;
}
if (jt->y1 > w.y1) {
q.push(Window(0, w.x1, w.y1, w.x2, jt->y1));
w.y1 = jt->y1;
}
if (jt->y2 < w.y2) {
q.push(Window(0, w.x1, jt->y2, w.x2, w.y2));
w.y2 = jt->y2;
}
}
}
double ans = 0;
while (!q.empty()) {
ans += (q.front().x2 - q.front().x1) * (q.front().y2 - q.front().y1);
q.pop();
}
fout << fixed << setprecision(3) << ans / tot * 100 << endl;
}
}
fin.close();
fout.close();
//system("pause");
return 0;
}
2. 三维矩形 TopCoder SRM191 Div2 1000-point CuboidJoin
class CuboidJoin {
struct Cuboid {
int x1, x2, y1, y2, z1, z2;
Cuboid(int x, int y, int z, int X, int Y, int Z) {
x1 = x, x2 = X, y1 = y, y2 = Y, z1 = z, z2 = Z;
}
};
public:
long long totalVolume(vector<int> cuboids) {
vector<Cuboid> lst;
const int sz = cuboids.size();
for (int i = 0; i < sz; i += 6) {
queue<Cuboid> q;
q.push(Cuboid(cuboids[i], cuboids[i + 1], cuboids[i + 2],
cuboids[i + 3], cuboids[i + 4], cuboids[i + 5]));
const int num = lst.size();
for (int j = 0; j < num && !q.empty(); ++j) {
const Cuboid const &d = lst[j];
int n = q.size();
while (n--) {
Cuboid c = q.front();
q.pop();
if (max(c.x1, d.x1) >= min(c.x2, d.x2) ||
max(c.y1, d.y1) >= min(c.y2, d.y2) ||
max(c.z1, d.z1) >= min(c.z2, d.z2)) {
q.push(c);
continue;
}
if (d.x1 > c.x1) {
q.push(Cuboid(c.x1, c.y1, c.z1, d.x1, c.y2, c.z2));
c.x1 = d.x1;
}
if (d.x2 < c.x2) {
q.push(Cuboid(d.x2, c.y1, c.z1, c.x2, c.y2, c.z2));
c.x2 = d.x2;
}
if (d.y1 > c.y1) {
q.push(Cuboid(c.x1, c.y1, c.z1, c.x2, d.y1, c.z2));
c.y1 = d.y1;
}
if (d.y2 < c.y2) {
q.push(Cuboid(c.x1, d.y2, c.z1, c.x2, c.y2, c.z2));
c.y2 = d.y2;
}
if (d.z1 > c.z1) {
q.push(Cuboid(c.x1, c.y1, c.z1, c.x2, c.y2, d.z1));
c.z1 = d.z1;
}
if (d.z2 < c.z2) {
q.push(Cuboid(c.x1, c.y1, d.z2, c.x2, c.y2, c.z2));
c.z2 = d.z2;
}
}
}
while (!q.empty()) {
lst.push_back(q.front());
q.pop();
}
}
long long ans = 0;
int k = lst.size();
for (int i = 0; i < k; ++i)
ans += ((long long)lst[i].x2 - lst[i].x1) * ((long long)lst[i].y2 - lst[i].y1) * ((long long)lst[i].z2 - lst[i].z1);
return ans;
}
};
3. 多维矩形
//toj 1074
//toj 1861
//usaco rect1
#include <cstdio>
#include <vector>
#include <list>
#include <algorithm>
using namespace std;
template<typename T>
class Rect
{
typedef pair<T,T> segment;
typedef vector<segment> space;
public:
void insert(const space& s)
{
q.push_back(s);
typename list<space>::iterator itr=q.end();
--itr;
while(q.begin()!=itr)
{
int i;
for(i=0;i<s.size();++i)
if(!cross(q.front()[i],s[i]))
break;
if(i<s.size())
{
q.push_back(q.front());
q.pop_front();
continue;
}
cut(q.front(),s,s.size()-1);
q.pop_front();
}
}
T area()
{
T ans(0);
typename list<space>::iterator itr=q.begin();
for(int i=0;i<q.size();i++,itr++)
{
T tmp=1;
for(int j=0;j<itr->size();j++)
tmp*=((*itr)[j].second-(*itr)[j].first);
ans+=tmp;
}
return ans;
}
private:
list<space> q;
void cut(space& a,const space& b,int d)
{
if(d==-1)
return;
space s;
if(b[d].first>a[d].first)
{
s=a;
s[d].second=b[d].first;
q.push_back(s);
a[d].first=b[d].first;
}
if(b[d].second<a[d].second)
{
s=a;
s[d].first=b[d].second;
q.push_back(s);
a[d].second=b[d].second;
}
cut(a,b,d-1);
}
inline bool cross(segment a,segment b)
{
return max(a.first,b.first)<min(a.second,b.second);
}
};
int main()
{
int n,T=0;
while(scanf("%d",&n),n)
{
Rect<double> r;
while(n--)
{
vector<pair<double,double> > rect;
double x1,y1,x2,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
rect.push_back(make_pair(x1,x2));
rect.push_back(make_pair(y1,y2));
r.insert(rect);
}
printf("Test case #%d\nTotal explored area: %.2lf\n\n",++T,r.area());
}
return 0;
}