版权声明:作为一个蒟蒻,转载时请通知我这个蒟蒻 https://blog.csdn.net/zyszlb2003/article/details/89875253
欢迎大家访问我的老师的OJ———caioj.cn
题面描述
思考
看完视频之后,
发现SCY讲得真(mo)好(hu)。
下面我来总结一下规律:
我们以 为原点,判断 到 , 到 是否是同一个方向旋转(注意是 到 , 到 ),可以利用叉乘来理解。
以 为原点的情况同理。
像上图就很好理解。
主要处理下列这种特殊情况。
这是以
为原点,
共点,它们叉乘之积为0。
我们再来一种普遍情况。
类似这样的,
共线,或其它两点或两点以上共线的,我们肯定有一个两两叉乘之积为
的结果,那么可以判断,现作为原点(即SCY中的标准点),以上图为例,我们可以判断
if(mul(p3,p2,p1)==0&&mymin(p1.x,p2.x)<=p3.x&&mymax(p1.x,p2.x)>=p3.x)return true;
是否在 这个范围之中,证明它是否有被覆盖。
但是这样还不行。
比如说:
所以我们还要再判断一下
是否在范围才行。
我们这里可以根据SCY贴在题面上的快速排斥实验来进行判断。
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(mymax(p1.x,p2.x)<mymin(p3.x,p4.x)||mymax(p1.y,p2.y)<mymin(p3.y,p4.y)
||mymax(p3.x,p4.x)<mymin(p1.x,p2.x)||mymax(p3.y,p4.y)<mymin(p1.y,p2.y))return false;
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)return true;
if(mul(p2,p4,p1)==0&&mymin(p1.x,p2.x)<=p4.x&&mymax(p1.x,p2.x)>=p4.x)return true;
if(mul(p1,p4,p3)==0&&mymin(p3.x,p4.x)<=p1.x&&mymax(p3.x,p4.x)>=p1.x)return true;
if(mul(p4,p2,p3)==0&&mymin(p3.x,p4.x)<=p2.x&&mymax(p3.x,p4.x)>=p2.x)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;
}