zoj 1886 || poj 2540 || UVA 10084 Hotter Colder

211 篇文章 0 订阅
134 篇文章 1 订阅

这题应该是经典题了吧,要不三个OJ都有。。。

0 0 到 10,10区域中有个东西,你在0,0点,如果你走到某个点然后会告诉你离那个东西是近了还是远了。近了就是hotter 远了是colder,如果距离不变的话,就是same。

这样的话,等于每次走一次就确定一个半平面区域,也就是从这个点到另一个点的中垂线然后分割成的半平面,自己可以画图。根据hotter或者colder确定是半平面的方向。

N*LOGN的模板,不过需要注意几点。

1)半平面的方向,我是默认半平面的方向为左侧区域,然后用线段表示的时候注意下

2)如果面积为0 那么以后都输出0。这点没判断,然后zoj过不去 = =。。。。

3)出现same就为0.0。开始判断如果出现重复点就不判断,后来这个判断删了也没事,估计数据没有这种。

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <stack>
#include <climits>

using namespace std;

const int MAX = 55;

struct point {double x,y;};
struct line { point a,b; double ang;};
line ln[MAX],deq[MAX],ltmp[MAX];
point s[MAX];
const double eps = 1e-6;
bool dy(double x,double y)	{	return x > y + eps;}	// x > y 
bool xy(double x,double y)	{	return x < y - eps;}	// x < y 
bool dyd(double x,double y)	{ 	return x > y - eps;}	// x >= y 
bool xyd(double x,double y)	{	return x < y + eps;} 	// x <= y 
bool dd(double x,double y) 	{	return fabs( x - y ) < eps;}  // x == y
double crossProduct(point a,point b,point c)//向量 ac 在 ab 的方向 
{
	return (c.x - a.x)*(b.y - a.y) - (b.x - a.x)*(c.y - a.y);
}
void makeline(double x1,double y1,double x2,double y2,line &l)
{
	l.a.x = x1; l.a.y = y1; l.b.x = x2; l.b.y = y2;
	l.ang = atan2(y1 - y2,x1 - x2);
}
point foot_line(point a,point l1,point l2)	//ac在l1l2的逆时针方向 
{										
	point c;
    c.x = a.x - l2.y + l1.y;
    c.y = a.y + l2.x - l1.x;
	return c;	
}
bool cmphp(line a,line b)
{
	if( dd(a.ang,b.ang) ) return xy(crossProduct(b.a,b.b,a.a),0.0);
	return xy(a.ang,b.ang);
}
bool equalcmp(line a,line b)
{
	return dd(a.ang,b.ang);
}
bool parallel(line u,line v)
{
	return dd( (u.a.x - u.b.x)*(v.a.y - v.b.y) - (v.a.x - v.b.x)*(u.a.y - u.b.y) , 0.0 );
}
bool equalp(point a,point b)
{
	return dd(a.x,b.x) && dd(a.y,b.y);
}
double area_polygon(point p[],int n)
{
	double s = 0.0;
	for(int i=0; i<n; i++)
		s += p[(i+1)%n].y * p[i].x - p[(i+1)%n].x * p[i].y;
	return fabs(s)/2.0;
}
point l2l_inst_p(line l1,line l2)
{
	point ans = l1.a;
	double t = ((l1.a.x - l2.a.x)*(l2.a.y - l2.b.y) - (l1.a.y - l2.a.y)*(l2.a.x - l2.b.x))/
			   ((l1.a.x - l1.b.x)*(l2.a.y - l2.b.y) - (l1.a.y - l1.b.y)*(l2.a.x - l2.b.x));
	ans.x += (l1.b.x - l1.a.x)*t;
	ans.y += (l1.b.y - l1.a.y)*t;
	return ans;
}
void inst_hp_nlogn(line *ln,int n,point *s,int &len)
{
	len = 0;
	sort(ln,ln+n,cmphp);
	n = unique(ln,ln+n,equalcmp) - ln;
	int bot = 0,top = 1;
	deq[0] = ln[0]; deq[1] = ln[1];
	for(int i=2; i<n; i++)
	{
		if( parallel(deq[top],deq[top-1]) || parallel(deq[bot],deq[bot+1]) )
			return ;
		while( bot < top && dy(crossProduct(ln[i].a,ln[i].b,
			l2l_inst_p(deq[top],deq[top-1])),0.0) )
			top--;
		while( bot < top && dy(crossProduct(ln[i].a,ln[i].b,
			l2l_inst_p(deq[bot],deq[bot+1])),0.0) )
			bot++;
		deq[++top] = ln[i];
	}
	while( bot < top && dy(crossProduct(deq[bot].a,deq[bot].b,
		l2l_inst_p(deq[top],deq[top-1])),0.0) )
		top--;
	while( bot < top && dy(crossProduct(deq[top].a,deq[top].b,
		l2l_inst_p(deq[bot],deq[bot+1])),0.0) )
		bot++;
		
	if( top <= bot + 1 ) return ;
	
	for(int i=bot; i<top; i++)
		s[len++] = l2l_inst_p(deq[i],deq[i+1]);

	if( bot < top + 1 ) s[len++] = l2l_inst_p(deq[bot],deq[top]);
	
	len = unique(s,s+len,equalp) - s;
}
int main()
{
	double x,y;
	char str[100];
	point a,b;
	a.x = a.y = 0.0 ;
	int cnt = 0;
	double area = 1e20;
	makeline(0,0,10,0,ln[cnt++]);
	makeline(10,0,10,10,ln[cnt++]);
	makeline(10,10,0,10,ln[cnt++]);
	makeline(0,10,0,0,ln[cnt++]);
	while( ~scanf("%lf%lf%s",&b.x,&b.y,str) )
	{
		if( strcmp(str,"Same") == 0 )
			area = 0.0;
		point c; c.x = (a.x + b.x)/2.0;
		c.y = (a.y + b.y)/2.0;
		point d;
		if( strcmp(str,"Colder") == 0 )
		{
			d = foot_line(c,a,b);
			makeline(c.x,c.y,d.x,d.y,ln[cnt++]);
		}
		if( strcmp(str,"Hotter") == 0 )
		{
			d = foot_line(c,a,b);
			makeline(d.x,d.y,c.x,c.y,ln[cnt++]);
		}
		a = b;
		if( area == 0.0 )
		{
			printf("0.00\n");
			continue;
		}
		int len = 0;
		memcpy(ltmp,ln,sizeof(ln));
		inst_hp_nlogn(ltmp,cnt,s,len);

		area = area_polygon(s,len);
		
		if( len < 3 )
		{
			printf("0.00\n");
			continue;
		}
		printf("%.2lf\n",area);
	}

return 0;
}

O N^2的

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <stack>
#include <climits>

using namespace std;

const int MAX = 55;

struct point {double x,y;};
point p[MAX];
const double eps = 1e-6;
bool dy(double x,double y)	{	return x > y + eps;}	// x > y 
bool xy(double x,double y)	{	return x < y - eps;}	// x < y 
bool dyd(double x,double y)	{ 	return x > y - eps;}	// x >= y 
bool xyd(double x,double y)	{	return x < y + eps;} 	// x <= y 
bool dd(double x,double y) 	{	return fabs( x - y ) < eps;}  // x == y
double crossProduct(point a,point b,point c)//向量 ac 在 ab 的方向 
{
	return (c.x - a.x)*(b.y - a.y) - (b.x - a.x)*(c.y - a.y);
}
point foot_line(point a,point l1,point l2)	//ac在l1l2的逆时针方向 
{										
	point c;
    c.x = a.x - l2.y + l1.y;
    c.y = a.y + l2.x - l1.x;
	return c;	
}
double area_polygon(point p[],int n)
{
	double s = 0.0;
	for(int i=0; i<n; i++)
		s += p[(i+1)%n].y * p[i].x - p[(i+1)%n].x * p[i].y;
	return fabs(s)/2.0;
}
point l2l_inst_p(point u1,point u2,point v1,point v2)
{
	point ans = u1;
	double t = ((u1.x - v1.x)*(v1.y - v2.y) - (u1.y - v1.y)*(v1.x - v2.x))/
				((u1.x - u2.x)*(v1.y - v2.y) - (u1.y - u2.y)*(v1.x - v2.x));
	ans.x += (u2.x - u1.x)*t;
	ans.y += (u2.y - u1.y)*t;
	return ans;
}
void makepoint(double x,double y,int &n)
{
	p[n].x = x; p[n++].y = y;
}
void cut_hp(point a,point b,point *s,int &len)
{
	int tc = 0;
	point tp[MAX];
	for(int i=0; i<=len; i++)
		tp[i] = s[i];
	for(int i=0; i<=len; i++)
	{
		if( xyd(crossProduct(a,b,tp[i]),0.0) )
			s[tc++] = tp[i];
		if( xy(crossProduct(a,b,tp[i])* 
				crossProduct(a,b,tp[i+1]),0.0) )
			s[tc++] = l2l_inst_p(a,b,tp[i],tp[i+1]);
	}
	s[tc] = s[0];
	len = tc;
}
int main()
{
	double x,y;
	char str[100];
	point a,b,c,d;
	a.x = a.y = 0.0 ;
	double area = 1e20;
	int len = 0;
	makepoint(0,0,len);
	makepoint(10,0,len);
	makepoint(10,10,len);
	makepoint(0,10,len);
	p[4] = p[0];
	while( ~scanf("%lf%lf%s",&b.x,&b.y,str) )
	{
		if( strcmp(str,"Same") == 0 )
			area = 0.0;
		c.x = (a.x + b.x)/2.0;
		c.y = (a.y + b.y)/2.0;
		if( strcmp(str,"Colder") == 0 )
			d = foot_line(c,a,b);
		if( strcmp(str,"Hotter") == 0 )
		{
			d = foot_line(c,a,b);
			swap(c,d);
		}
		a = b;
		if( area == 0.0 )
		{
			printf("0.00\n");
			continue;
		}
		cut_hp(c,d,p,len);
		area = area_polygon(p,len);
		
		if( len < 3 )
		{
			printf("0.00\n");
			continue;
		}
		printf("%.2lf\n",area);
	}
return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值