矩形切割

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;
}


發佈了52 篇原創文章 · 獲贊 2 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章