题目链接:http://poj.org/problem?id=2653
Pick-up sticks
题目大意:给你n条线段,依次放入平面直角坐标系中,先放的,如果与后面放的线段相交,则被压住,最后要你统计没被压住的线段的个数。
直接套线段相交的模板即可!!!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const double eps=1e-10;
struct point
{
double x,y;
}p[100010],q[100010];
int vis[100010];
bool inter(point a,point b,point c,point d)
{
if(min(a.x,b.x)>max(c.x,d.x)||min(a.y,b.y)>max(c.y,d.y)||min(c.x,d.x)>max(a.x,b.x)||min(c.y,d.y)>max(a.y,b.y))
return 0;
double h,i,j,k;
h=(b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
i=(b.x-a.x)*(d.y-a.y)-(b.y-a.y)*(d.x-a.x);
j=(d.x-c.x)*(a.y-c.y)-(d.y-c.y)*(a.x-c.x);
k=(d.x-c.x)*(b.y-c.y)-(d.y-c.y)*(b.x-c.x);
return h*i<=eps&&j*k<=eps;
}
int main()
{
int n;
while(scanf("%d",&n),n)
{
int i,j;
memset(vis,0,sizeof(vis));
for(i=1;i<=n;i++)
scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&q[i].x,&q[i].y);
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++)
{
if(inter(p[i],q[i],p[j],q[j]))
{
vis[i]=1;
break;
}
}
printf("Top sticks:");
for(i=1;i<=n;i++)
if(!vis[i])
{
printf(" %d",i);
break;
}
for(i++;i<=n;i++)
if(!vis[i])
printf(", %d",i);
printf(".\n");
}
return 0;
}