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