在二维平面随机扔木棍,找出最顶上的没有被别的木棍压着的木棍,输出这些木棍的序号。
核心算法就是线段相交:
函数最后两句是判断这两条直线的相交,因为是线段,所以要加上线段端点的约束。
bool inter(pline l1,pline l2)
{
return
max(l1.st.x,l1.ed.x) >= min(l2.st.x,l2.ed.x) &&
max(l2.st.x,l2.ed.x) >= min(l1.st.x,l1.ed.x) &&
max(l1.st.y,l1.ed.y) >= min(l2.st.y,l2.ed.y) &&
max(l2.st.y,l2.ed.y) >= min(l1.st.y,l1.ed.y) &&
dcmp((l2.st-l1.st)^(l1.ed-l1.st))*dcmp((l2.ed-l1.st)^(l1.ed-l1.st)) <= 0 &&
dcmp((l1.st-l2.st)^(l2.ed-l2.st))*dcmp((l1.ed-l2.st)^(l2.ed-l2.st)) <= 0;
}
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define FOR(i,n) for(int i=0;i<n;++i)
const double epx = 1e-8;
struct pnode
{
double x,y;
pnode(){}
pnode( double a,double b):x(a),y(b){}
double operator ^ (const pnode &b)const
{
return x*b.y - y * b.x;
}
double operator *(const pnode&b)const
{
return x*b.x + y * b.y;
}
pnode operator - (const pnode &b)const
{
return pnode(x-b.x,y-b.y);
}
};
double cross( pnode p0,pnode p1,pnode p2)
{
return (p1-p0) ^ (p2-p0);
}
int dcmp( double x)
{
if( fabs(x) <epx )
return 0;
return x < 0 ? -1:1;
}
struct pline
{
pnode st,ed;
pline (){}
pline(pnode a,pnode b):st(a),ed(b){}
void readl(){ scanf("%lf %lf %lf %lf",&st.x,&st.y,&ed.x,&ed.y); }
};
const int MX = 100005;
bool vis[MX];
pline line[MX];
bool inter(pline l1,pline l2)
{
return
max(l1.st.x,l1.ed.x) >= min(l2.st.x,l2.ed.x) &&
max(l2.st.x,l2.ed.x) >= min(l1.st.x,l1.ed.x) &&
max(l1.st.y,l1.ed.y) >= min(l2.st.y,l2.ed.y) &&
max(l2.st.y,l2.ed.y) >= min(l1.st.y,l1.ed.y) &&
dcmp((l2.st-l1.st)^(l1.ed-l1.st))*dcmp((l2.ed-l1.st)^(l1.ed-l1.st)) <= 0 &&
dcmp((l1.st-l2.st)^(l2.ed-l2.st))*dcmp((l1.ed-l2.st)^(l2.ed-l2.st)) <= 0;
}
int main()
{
int n;
double x,y,x1,y1;
while( scanf("%d",&n) && n)
{
for( int i=0;i<n;++i)
{
scanf("%lf %lf %lf %lf",&x,&y,&x1,&y1);
line[i] = pline( pnode(x,y),pnode(x1,y1) );
vis[i] = true;
}
for( int i = 0;i<n;++i)
for( int j = i+1;j<n;++j)
if( inter(line[i],line[j]))
{
vis[i] = false;
break;
}
printf("Top sticks: ");
int f = 0;
FOR(i,n)
{
if( vis[i])
{
if( f == 0)
f = 1;
else printf(", ");
printf("%d",i+1);
}
}
printf(".\n");
}
return 0;
}