POJ3384 Feng Shui

挖坟= =

为了克服计算几何恐惧症来写的

然后特么 spj有锅

本地测应该是没啥问题的= =

自闭了= =

这个题就是每条边往里移R

然后求半平面交

再找个最远点对

旋转卡壳或者枚举都可以

sbspj浪费青春= =

透他妈= =

//Love and Freedom.
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define inf 20021225
#define ll long long
#define db double
#define eps 1e-12
#define debug printf("-------------\n")
using namespace std;

struct poi
{
	db x,y;
	poi(){}
	poi(db _x,db _y){x=_x,y=_y;}
};

typedef poi vec;
vec operator +(vec a,vec b){return vec(a.x+b.x,a.y+b.y);}
vec operator -(vec a,vec b){return vec(a.x-b.x,a.y-b.y);}
vec operator *(vec a,db b){return vec(a.x*b,a.y*b);}
db mul(vec a,vec b){return a.x*b.y-a.y*b.x;}
db val(vec a,vec b){return a.x*b.x+a.y*b.y;}
db len(vec a){return sqrt(a.x*a.x+a.y*a.y);}
db ang(vec a){return atan2(a.y,a.x);}

struct line{poi p;vec v;db ang;};
bool cmp(line a,line b)
{
	if(abs(a.ang-b.ang)<eps)	return mul(b.v+b.p-a.p,a.v)>eps;
	return a.ang<b.ang;
}
bool onleft(line l,poi p)
{
	return mul(l.p-p,l.v+l.p-p)>0;
}
poi section(line a,line b)
{
	db k = mul(a.v+a.p-b.p,a.p-b.p)/(mul(a.v+a.p-b.p,b.v)+mul(b.v,a.p-b.p));
	return b.p+b.v*k;
}
struct polygon
{
	poi p[210],s[210]; int n,cnt; db r;
	line l[210]; int que[210],hd,tl;
	poi a1,a2;
	void put(poi a)
	{
		printf("%lf %lf\n",a.x,a.y);
	}
	void scan()
	{
		scanf("%d%lf",&n,&r);
		r -= eps;
		for(int i=1;i<=n;i++)
			scanf("%lf%lf",&p[i].x,&p[i].y);
		reverse(p+2,p+n+1);
		for(int i=1;i<=n;i++)
		{
			l[i].p = p[i];
			l[i-1?i-1:n].v = p[i] - l[i-1?i-1:n].p;
		}
		l[n].v = p[1] - l[n].p;
		//printf("%lf %lf",l[n].v.x,l[n].v.y);
	}
	void movein()
	{
		for(int i=1;i<=n;i++)
		{
			vec tmp = l[i].v;
			db xx = tmp.x, yy= tmp.y;
			tmp.y = xx; tmp.x = -yy;
			db delta = r/len(tmp);// delta*=delta;
			//put(tmp); printf("%lf\n",delta);
			tmp = tmp*delta;// vec qwq=l[i].p;
			l[i].p = l[i].p + tmp;
			//printf("%lf ",len(l[i].p-qwq));
			l[i].ang = ang(l[i].v);
			//printf("%lf\n",l[i].ang);
			//put(l[i].p); put(l[i].v);
			//printf("---------------\n");
		}
	}
	void halfplane()
	{
		sort(l+1,l+n+1,cmp);
		//printf("%d\n",onleft(l[1],poi(0,0)));
		//put(l[1].p); put(l[1].v);
		//put(l[2].p); put(l[2].v);
		//put(section(l[1],l[2]));
		hd = tl = 1; que[hd] =1;
		for(int i=2;i<=n;i++)
		{
			while(hd<tl && !onleft(l[i],s[tl-1]))	tl--;
			while(hd<tl && !onleft(l[i],s[hd]))	hd++;
			que[++tl] = i; //printf("%d %d %d\n",i,hd,tl);
			//put(l[i].p); put(l[i].v); debug;
			if(hd<tl)	s[tl-1] = section(l[que[tl]],l[que[tl-1]]);
		}
		while(hd<tl && !onleft(l[que[hd]],s[tl-1]))
		{
			//printf("%d %d\n",hd,tl);
			//put(l[que[hd]].p); put(l[que[hd]].v);
			//put(s[tl-1]); debug;
			tl--;
		}
		if(hd<tl)	s[tl] = section(l[que[tl]],l[que[hd]]);
		//for(int i=hd;i<=tl;i++)	put(s[i]);
	}
	void solve()
	{
		scan();
		movein();
		halfplane();
		db ans=0.0;int tmp=hd+1;
		s[tl+1] = s[hd];
		for(int i=hd;i<=tl;i++)
		{
			//printf("QAQ");
			int nxt = tmp+1>tl?hd:tmp+1;
			while(mul(s[nxt]-s[i],s[nxt]-s[i+1])>mul(s[tmp]-s[i],s[tmp]-s[i+1]))	tmp=tmp+1>tl?hd:tmp+1,nxt=nxt+1>tl?hd:nxt+1;
			//printf("%lf\n",len(s[tmp]-s[i]));
			if(ans < len(s[tmp]-s[i]))
				ans = len(s[tmp]-s[i]),a1=s[tmp],a2=s[i];
		}
		/**for(int i=hd;i<=tl;i++)
		for(int j=i+1;j<=tl;j++)
		if(len(s[i]-s[j])>=ans)
			a1=s[i],a2=s[j],ans=len(s[i]-s[j]);*/
		printf("%.10lf %.10lf %.10lf %.10lf\n",a1.x,a1.y,a2.x,a2.y);
	}
}poly;
int main()
{
	poly.solve();
	return 0;
}

 

转载于:https://www.cnblogs.com/hanyuweining/p/10321886.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值