半平面交

不会啊 ! 等待不吭!!!

bzoj 2618


#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
int n, m;
int read()
{
	int x = 0, f = 1; char ch = getchar();
	while (ch<'0' || ch>'9'){ if (ch == '-')f = -1; ch = getchar(); }
	while (ch >= '0'&&ch <= '9'){ x = x * 10 + ch - '0'; ch = getchar(); }
	return x*f;
}
struct point
{
	double x, y;
}p[1000];
double operator*(point a, point b)
{
	return a.x*b.y - a.y*b.x;
}
point operator-(point a, point b)
{
	point c;
	c.x = a.x - b.x;
	c.y = a.y - b.y;
	return c;
}
struct line
{
	point a, b;
	point direction;
	double slope;
	bool operator<(line c)
	{
		if (slope != c.slope)
			return slope < c.slope;
		return direction*(c.a-a) > 0;
	}
	point inter(line c)//找交点的代码..挑战上有
	{
		double t = (c.a - a)*(c.b - c.a) / ((b - a)*(c.b - c.a));
		point cc;
		cc.x = a.x + t*(b - a).x;
		cc.y = a.y + t*(b - a).y;
		return cc;
	}

};
bool com(line a, line b)//排序slope越小越靠前相同slope 选靠里的
{
	if (a.slope != b.slope)
		return a.slope < b.slope;
	else
	return a.direction*(b.a - a.a) > 0;
}
line l[1000],workline[1000],stack[1000];
point finall[1000];
int sleft, sright;
int all = 0,tot=0;

bool judge(line a, line b, line c)//看交点是否在外面若在则将r--或者是l++
{
	point com = a.inter(b);
	com = com - c.a;
	return c.direction*com <=0;
}

int main()
{
	
	n = read();
	while (n--)
	{
		scanf("%d", &m);
		for (int i = 0; i < m; i++)
		{
			scanf("%lf%lf", &p[i].x, &p[i].y);
		}
		for (int i = 0; i < m-1; i++)
		{
			l[all].a = p[i];
			l[all].b = p[i + 1];
			l[all].direction= p[i+1] - p[i];
			l[all].slope = atan2(l[all].direction.y, l[all].direction.x);
			all++;
		}
		l[all].a = p[m - 1];
		l[all].b = p[0];
		l[all].direction= p[0] - p[m-1];
		l[all].slope = atan2(l[all].direction.y, l[all].direction.x);
		all++;
	}
	sort(l, l + all,com);
	/*cout << endl;
	cout << "排序后的线:" << endl;
	for (int i = 0; i < all; i++)
		cout << l[i].direction.x << " " << l[i].direction.y << " "<<l[i].a.x<<" "<<l[i].a.y<<" "<<l[i].b.x<<" "<<l[i].b.y<<endl;*/
	int cnt = 0;
	for (int i = 0; i < all-1; i++)
	{
		if (l[i].slope != l[i + 1].slope)workline[cnt++] = l[i];
		//if (l[i].slope == l[i + 1].slope)
			//cout << "ok" << endl;
	}
		workline[cnt++] = l[all - 1];
	/*	cout << endl;
		cout << "过滤后的线:" << endl;
		for (int i = 0; i < cnt; i++)
		{
			cout << workline[i].direction.x << " " << workline[i].direction.y <<" "<<workline[i].a.x<<" "<<workline[i].a.y<<" "<<workline[i].b.x<<" "<<workline[i].b.y<<endl;
		}*/
		sleft = 0;
		sright = 0;
		stack[sright++] = workline[0];
		stack[sright++] = workline[1];
		for (int i = 2; i < cnt; i++)
		{
			//if (i == 2)
			//	cout <<"testt:" << judge(workline[sleft], workline[sleft + 1], workline[i]) << "sleft:"<<sleft<<" "<<"right:"<<sright<<endl;
			while ((sright - sleft >= 2) && judge(workline[sright - 1], workline[sright - 2], workline[i]))sright--;
			while ((sright-sleft>=2)&&judge(workline[sleft], workline[sleft + 1], workline[i]))sleft++;
			
			workline[sright++] = workline[i];
		}
		while ((sright - sleft >= 2) && (judge(workline[sright - 1], workline[sright - 2], workline[sleft])))sright--;
		while ((sright - sleft >= 2) && (judge(workline[sleft], workline[sleft + 1], workline[sright - 1])))sleft++;
		workline[sright] = workline[sleft];
		/*cout << endl;
		cout << "算法后的线:" << endl;
		for (int i = sleft; i < sright; i++)
		{
			cout << workline[i].direction.x << " " << workline[i].direction.y <<" "<<workline[i].a.x<<" "<<workline[i].a.y<<" "<<workline[i].b.x<<" "<<workline[i].b.y<< endl;
		}*/
		cnt = 0;
		for (int i = sleft; i < sright; i++)
		{
			finall[cnt++] = workline[i].inter(workline[i+1]);
		}
		finall[cnt] = finall[0];
		/*cout << endl;
		cout << "所有交点:" << endl;
		for (int i = 0; i < cnt; i++)
		{
			cout << finall[i].x << " " << finall[i].y << endl;
		}*/
		if (cnt >= 2)
		{
			double size = 0;
			for (int i = 0; i < cnt; i++)
			{
				size += finall[i] * finall[i + 1];
			}
			size = fabs(size) / 2;
			printf("%.3lf\n", size);
		}
		else
		{
			printf("%.3lf\n", 0);
		}
}

错误代码等待修改....................

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值