标签:acm
打算好好练练计算几何。
昨天经过反省决定戒掉一做题就看题解的恶习,结果今天做题就抓瞎了。。。
因为刚开始有很多公式方法不知道,所以完全自己做就毫无思路= =。还是忍住没看题解,打开了手边的CLRS,我本来以为这里面关于计算几何的篇幅很少,应该讲不了什么。
然后我发现我错了,经典就是经典。关于判断线段相交的方法,讲的非常清楚,每一步包括叉乘等细节都有很详细的讲解。
看完之后手动敲,1A,代码:
#include <stdio.h>
#include <math.h>
#include <algorithm>
using namespace std;
#define esp 1e-8
typedef struct Point
{
double x,y;
}Point;
struct Line
{
Point a,b;
}l[110];
double direction(Point pi,Point pj,Point pk) //叉乘判断点pk在线段的哪一侧
{
return (pk.x-pi.x)*(pj.y-pi.y)-(pj.x-pi.x)*(pk.y-pi.y);
}
bool on_segment(Point pi,Point pj,Point pk) //判断点pk是否在线段pi_pk上
{
if(pk.x>=min(pi.x,pj.x)&&pk.x<=max(pi.x,pj.x)&&pk.y>=min(pi.y,pj.y)&&pk.y<=max(pi.y,pj.y))
return true;
else
return false;
}
bool judge(Point p1,Point p2,Point p3,Point p4)
{
int d1=direction(p3,p4,p1);
int d2=direction(p3,p4,p2);
int d3=direction(p1,p2,p3);
int d4=direction(p1,p2,p4);
if(((d1>0&&d2<0)||(d1<0&&d2>0))&&((d3>0&&d4<0)||(d3<0&&d4>0))) //分别判断两组点,满足每一组的两个点都不在同一侧即可确定相交
return true;
else if(d1==0&&on_segment(p3,p4,p1)) //端点在线段上也算相交,下同
return true;
else if(d2==0&&on_segment(p3,p4,p2))
return true;
else if(d3==0&&on_segment(p1,p2,p3))
return true;
else if(d4==0&&on_segment(p1,p2,p4))
return true;
else
return false;
}
int main(int argc, char const *argv[])
{
//freopen("H:\\in.txt","r",stdin);
int n;
while(scanf("%d",&n),n)
{
int cnt=0;
for(int i=0;i<n;i++)
scanf("%lf%lf%lf%lf",&l[i].a.x,&l[i].a.y,&l[i].b.x,&l[i].b.y);
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++)
if(judge(l[i].a,l[i].b,l[j].a,l[j].b))
cnt++;
printf("%d\n",cnt);
}
return 0;
}
HDOJ 1086 You can Solve a Geometry Problem too
标签:acm
原文地址:http://blog.csdn.net/dreamon3/article/details/45268803