欢迎大家访问我的老师的OJ———caioj.cn
题面描述
思考
看完视频之后,
发现SCY讲得真(mo)好(hu)。
下面我来总结一下规律:
我们以 p 1 p_1 p1为原点,判断 p 3 p_3 p3到 p 2 p_2 p2, p 2 p_2 p2到 p 4 p_4 p4是否是同一个方向旋转(注意是 p 3 p_3 p3到 p 2 p_2 p2, p 2 p_2 p2到 p 4 p_4 p4),可以利用叉乘来理解。
以 p 3 p_3 p3为原点的情况同理。
像上图就很好理解。
主要处理下列这种特殊情况。
这是以
p
1
p_1
p1为原点,
p
2
,
p
3
p_2,p_3
p2,p3共点,它们叉乘之积为0。
我们再来一种普遍情况。
类似这样的,
p
2
,
p
3
p_2,p_3
p2,p3共线,或其它两点或两点以上共线的,我们肯定有一个两两叉乘之积为
0
0
0的结果,那么可以判断,现作为原点(即SCY中的标准点),以上图为例,我们可以判断
if(mul(p3,p2,p1)==0&&mymin(p1.x,p2.x)<=p3.x&&mymax(p1.x,p2.x)>=p3.x)return true;
p 3 . x p_3.x p3.x是否在 [ m i n ( p 1 . x , p 2 . x ) , m a x ( p 1 . x , p 2 . x ) ] [min(p_1.x,p_2.x),max(p_1.x,p_2.x)] [min(p1.x,p2.x),max(p1.x,p2.x)]这个范围之中,证明它是否有被覆盖。
但是这样还不行。
比如说:
所以我们还要再判断一下
y
y
y是否在范围才行。
AC code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using namespace std;
const int N=1e4+10;
struct node{double x,y;};
struct line{node p1,p2;}a[N];
double mul(node p1,node p2,node p0)
{
double x1=p1.x-p0.x,x2=p2.x-p0.x;
double y1=p1.y-p0.y,y2=p2.y-p0.y;
return x1*y2-x2*y1;
}
double mymin(double x,double y){return x<y?x:y;}
double mymax(double x,double y){return x>y?x:y;}
bool pd(line l1,line l2)
{
node p1=l1.p1;
node p2=l1.p2;
node p3=l2.p1;
node p4=l2.p2;
if(mul(p3,p2,p1)*mul(p2,p4,p1)>0&&mul(p1,p4,p3)*mul(p4,p2,p3)>0)return true;
if(mul(p3,p2,p1)==0&&mymin(p1.x,p2.x)<=p3.x&&mymax(p1.x,p2.x)>=p3.x&&mymin(p1.y,p2.y)<=p3.y&&mymax(p1.y,p2.y)>=p3.y)return true;
if(mul(p2,p4,p1)==0&&mymin(p1.x,p2.x)<=p4.x&&mymax(p1.x,p2.x)>=p4.x&&mymin(p1.y,p2.y)<=p4.y&&mymax(p1.y,p2.y)>=p4.y)return true;
if(mul(p1,p4,p3)==0&&mymin(p3.x,p4.x)<=p1.x&&mymax(p3.x,p4.x)>=p1.x&&mymin(p3.y,p4.y)<=p1.y&&mymax(p3.y,p4.y)>=p1.y)return true;
if(mul(p4,p2,p3)==0&&mymin(p3.x,p4.x)<=p2.x&&mymax(p3.x,p4.x)>=p2.x&&mymin(p3.y,p4.y)<=p2.y&&mymax(p3.y,p4.y)>=p2.y)return true;
return false;
}
int b[N];
int main()
{
int n;scanf("%d",&n);int tot=0;
for(int i=1;i<=n;i++)scanf("%lf%lf%lf%lf",&a[i].p1.x,&a[i].p1.y,&a[i].p2.x,&a[i].p2.y);
for(int i=1;i<=n;i++)
{
bool bk=true;
for(int j=i+1;j<=n;j++)
if(pd(a[i],a[j])){bk=false;break;}
if(bk)b[++tot]=i;
}
for(int i=1;i<tot;i++)printf("%d ",b[i]);
printf("%d\n",b[tot]);
return 0;
}