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