⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pku1151.cpp

📁 POJ1151 Atlantis的源代码
💻 CPP
字号:
///POJ1151 Atlantis 
///线段树 segment tree 求面积

#include <cstdio>
#include <algorithm>
using namespace std;

const int MAX_ELem = 400;
const int MAX_Line = 200;
struct Node{
	short left, right;
	bool coverd;
	double len;
	//short segment;
	short count;
	bool leftcover, rightcover;
	struct Node *lcd, *rcd;
	void Build(int, int);
	void Update();
	void Insert(double, double);
	void Delete(double, double);
}SegTree[MAX_ELem];
struct Node *root = &SegTree[0];
struct Data{
	double x, y1, y2;
	bool left;
}line[MAX_Line];
double node_val[MAX_Line];
int up = 0;

void Node::Build(int l, int r)
{
	left = l;
	right = r;
	coverd = 0;
	len = 0;
	//segment = 0;
	count = 0;
	leftcover = rightcover = 0;
	if(r-l>1){
		int lenid = (l + r) / 2;
		lcd = &SegTree[++up];
		lcd->Build(l, lenid);
		rcd = &SegTree[++up];
		rcd->Build(lenid, r);
	}
}

void Node::Update()
{
	if(count>0){
		len = node_val[right] - node_val[left];
		//segment = 1;
		leftcover = rightcover = 1;
	}else if(right-left==1){
		len = 0;
		//segment= 0;
		leftcover = rightcover = 0;
	}else{
		len = lcd->len + rcd->len;
		//segment = lcd->segment + rcd->segment;
		//if(lcd->rightcover && rcd->leftcover)segment--;
		leftcover = lcd->leftcover;
		rightcover = rcd->rightcover;
	}
}

void Node::Insert(double l, double r)
{
	if(l<=node_val[left] && node_val[right]<=r){
		count++;
	}else{
		if(l<node_val[lcd->right]){
			lcd->Insert(l, r);
		}
		if(r>node_val[rcd->left]){
			rcd->Insert(l, r);
		}
	}
	Update();
}

void Node::Delete(double l, double r)
{
	if(l<=node_val[left] && node_val[right]<=r){
		count--;
	}else{
		if(l<node_val[lcd->right]){
			lcd->Delete(l, r);
		}
		if(r>node_val[rcd->left]){
			rcd->Delete(l, r);
		}
	}
	Update();
}

bool operator < (const Data &a, const Data &b)
{
	return a.x < b.x;
}

int main(int argc, char **argv) {
	//freopen("in","r",stdin);
	//freopen("out","w",stdout);
	int i, j, N, tstcs=1;
	double x1, y1, ans, x2, y2;
	while(scanf("%d",&N),N){
		i = 0;
		for(j=0;j<N;j++){
			scanf("%lf %lf %lf %lf",&x1, &y1, &x2, &y2);
			line[i].x = x1; line[i].y1 = y1; line[i].y2 = y2; line[i].left = 1; node_val[i++] = y1;
			line[i].x = x2; line[i].y1 = y1; line[i].y2 = y2; line[i].left = 0; node_val[i++] = y2;
		}
		N *= 2;
		sort(line, line+N);
		sort(node_val, node_val+N);
		j = 1;
		for(i=1;i<N;i++){
			if(node_val[i]!=node_val[i-1]){
				node_val[j++] = node_val[i];
			}
		}
		up = 0;
		ans = 0;
		//prev = 0;
		root->Build(0, j-1);
		for(i=0; i<N-1; i++){
			if(line[i].left){
				root->Insert(line[i].y1, line[i].y2);
			}else{
				root->Delete(line[i].y1, line[i].y2);
			}
			ans += (line[i+1].x - line[i].x)*root->len;
			//printf("ans = %lf\n",ans);
			//printf("segment = %d\n",root->segment);
			//printf("root->len = %lf\n",root->len);
			//printf("line[i+1].x = %lf\n",line[i+1].x);
			//printf("line[i].x = %lf\n\n",line[i].x);
			//ans += abs(root->len - prev);
			//prev = root->len;
		}
		//ans += root->len;
		printf("Test case #%d\n",tstcs++);
		printf("Total explored area: %.2lf\n\n",ans);
	}
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -