cf#13F - Letter A-计算几何

http://codeforces.com/contest/13/problem/B

给出 三个线段的起点,终点

让你判断是否组成一个A字母


条件如下:

1 有两线段同端点,并且第三条线段经过了前两条线段上的点,连接他们

2、有共同端点的两线段夹角大于零小于等于90度

3。 第三条线段分别把前两条线段截成两部分,要求被截出来的部分必须大于等于所在线段长度1/5,且小于等于4/5


没什么坑。。。老老实实做就是了。。注意一些细节就好


思路: 符合要求的六个点,必然是2个相同,四个分别不同

1、那么重复次数为2的点个数为1,重复次数为1的点个数为4;(共六个点)

2、找到重复的那个点后,从而确定哪两条是有公共端点的线段,然后求出他们的夹角(注意是>0&&《90)开始写成<90

3、判断第三条线段的端点S是否在line2,是求出其到line2一端的长度是否满足要求,同理判断另一侧


如果以上有任一不满足,say no。

都满足了。。say yes


参考code:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <cmath>
#include <iostream>
using namespace std;
const double pi=acos(-1.0);
struct POINT
{
	double x;
	double y; 
	POINT(__int64 a=0, __int64 b=0) { x=a; y=b;}

	bool operator==(POINT &B) const
	{
		return x==B.x&&y==B.y;
	}
	bool operator<(const POINT &b) const
	{
		if (x!=b.x)
		return x<b.x;
		else
			return y<b.y;
	}
};
struct LINESEG
{
	POINT s;
	POINT e;
	LINESEG(POINT a, POINT b) { s=a; e=b;}
	LINESEG() { }
};
double angle(POINT o,POINT e,POINT s)
{
	double cosfi,fi,norm;
	double dsx = s.x - o.x;
	double dsy = s.y - o.y;
	double dex = e.x - o.x;
	double dey = e.y - o.y;
	cosfi=dsx*dex+dsy*dey;
	norm=(dsx*dsx+dey*dey)*(dex*dex+dey*dey);
	cosfi /= sqrt( norm );
	if (cosfi >= 1.0 ) return 0;
	if (cosfi <= -1.0 ) return -3.1415926;
	fi=acos(cosfi);
	if (dsx*dey-dsy*dex>0) return fi;// 说明矢量os 在矢量 oe的顺时针方向
	return -fi;
}
double multiply(POINT sp,POINT ep,POINT op)
{
	return((sp.x-op.x)*(ep.y-op.y) - (ep.x-op.x)*(sp.y-op.y));
}
bool online(LINESEG l,POINT p)
{
	return ((multiply(l.e,p,l.s)==0)
		&& ( ( (p.x-l.s.x) * (p.x-l.e.x) <=0 ) && ( (p.y-l.s.y)*(p.y-l.e.y) <=0 ) ) );
}
double dist(POINT p1,POINT p2)
{
	return( sqrt( (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y) ) );
}
int main()
{
	int t;
	__int64 i ;
	cin>>t;
	__int64 x,y,x1,y1;
	LINESEG ll[5];
	while(t--)
	{
		__int64 vis[5];
		memset(vis,0,sizeof(vis));
		map<POINT,__int64 > sb;
		map<POINT,__int64 >::iterator it;
		sb.clear();
		__int64 tmp=1;
		while(tmp<=3)
		{
			scanf("%I64d%I64d%I64d%I64d",&x,&y,&x1,&y1);
			ll[tmp++]=LINESEG(POINT(x,y),POINT(x1,y1));
			sb[POINT(x,y)]++;
			sb[POINT(x1,y1)]++;
		}
		__int64 flag=0;
		__int64 cun=0;
		POINT who;
		who.x=who.y=-1;
		for (it=sb.begin();it!=sb.end();it++)
		{
			if (it->second==2)
			{flag=1;who=it->first;}
			else
				if (it->second==1)
					cun++;
		}
		__int64 ret=0;
		if (cun==4&&flag) ret=1;
		if (!ret) {printf("NO\n"); continue;}
		for (i=1;i<=3;i++)
		{
			if (ll[i].s==who||ll[i].e==who) vis[i]=1;
		}
		for (i=1;i<=3;i++)
		{if (vis[i]==0) break;}
		__int64 line2,line3,line1;
		if (i==1)
		{line1=1;line2=2;line3=3;}
		if (i==2)
		{line1=2;line2=1;line3=3;}
		if (i==3)
		{line1=3;line2=2;line3=1;}
		
		POINT P1,P2;
		if (ll[line2].s==who) P1=ll[line2].e;
		if (ll[line2].e==who) P1=ll[line2].s;
		if (ll[line3].s==who) P2=ll[line3].e;
		if (ll[line3].e==who) P2=ll[line3].s;
		
		__int64 flag_angle=0;
		double ret_angel=	angle(who,P1,P2); 
				if (ret_angel<0) ret_angel=-ret_angel;  
		if (ret_angel>0&&ret_angel<=pi/2) 
			flag_angle=1;
		ret_angel=	angle(who,P2,P1); 
				if (ret_angel<0) ret_angel=-ret_angel;  
		if (ret_angel>0&&ret_angel<=pi/2) 
			flag_angle=1;
 
		if (flag_angle==0) {printf("NO\n"); continue;}
		
		__int64 fla=0;
		double dis3=0;
		double dis2=0;
		if (online(ll[line2],ll[line1].s))
		{
			double line_dis=dist(ll[line2].s,ll[line2].e);
			dis2=dist(ll[line1].s,ll[line2].s);
			if (dis2*5>=line_dis && dis2*5<=line_dis*4)
				fla=1;
		}
		if (online(ll[line2],ll[line1].e))
		{
			double line_dis=dist(ll[line2].s,ll[line2].e);
			dis2=dist(ll[line1].e,ll[line2].s);
			if (dis2*5>=line_dis && dis2*5<=line_dis*4)
				fla=1;
		}
		if (fla==0) {printf("NO\n"); continue;}
 		fla=0;
		
		
		
		if (online(ll[line3],ll[line1].s))
		{
			double line_dis=dist(ll[line3].s,ll[line3].e);
			dis2=dist(ll[line1].s,ll[line3].s);
			if (dis2*5>=line_dis && dis2*5<=line_dis*4)
				fla=1;
		}
		if (online(ll[line3],ll[line1].e))
		{
			double line_dis=dist(ll[line3].s,ll[line3].e);
			dis2=dist(ll[line1].e,ll[line3].s);
			if (dis2*5>=line_dis && dis2*5<=line_dis*4)
				fla=1;
		}
		if (fla==0) {printf("NO\n"); continue;}
		else
			printf("YES\n");
		
	}   
	return 0;
	
}
//57283


你可能感兴趣的:(cf#13F - Letter A-计算几何)