http://poj.org/problem?id=2653
这道题目,我直接用暴力过的,刚开始交的C++一直超时,改成G++后就可以过
题意很好理解,就是让你找两线段是否相交,如果相交,那么编号大的一定在编号小的上面,就把编号小的标记就可以了
代码如下:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1002;
const int N=100002;
struct point
{
double x,y;
};
struct Seg
{
point a,b;
}s[N];
bool flag[N];
int a[maxn];
//重载最大值、最小值计算函数
double min(double x,double y)
{return x<y?x:y;}
double max(double x,double y)
{return x>y?x:y;}
//判断double型的正数、负数和0,分别相应的返回1、-1和0
int dblcmp(double x)
{
if(x==0) return 0;
return (x>0)?1:-1;
}
//计算叉积
double det(double x1,double y1,double x2,double y2)
{return x1*y2-x2*y1;}
//计算a,b,c三点的叉积,判断a,b,c三点的位置关系
double cross(point a,point b,point c)
{return det(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y);}
//计算两点间的最短距离
double dist(point a,point b)
{return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
//判断线段是否相交,相交为true,不相交为false
bool segcross(point a,point b,point c,point d)
{
int d1,d2,d3,d4;
d1=dblcmp(cross(a,b,c));
d2=dblcmp(cross(a,b,d));
d3=dblcmp(cross(c,d,a));
d4=dblcmp(cross(c,d,b));
if((d1^d2)==-2&&(d3^d4)==-2) return true;
return false;
}
int main()
{
int n;
while(scanf("%d",&n),n)
{
memset(flag,0,sizeof(flag));
for(int i=0;i<n;i++)
scanf("%lf%lf%lf%lf",&s[i].a.x,&s[i].a.y,&s[i].b.x,&s[i].b.y);
for(int i=0;i<n-1;i++)
for(int j=i+1;j<n;j++)
if(!flag[i]&&segcross(s[i].a,s[i].b,s[j].a,s[j].b))
{flag[i]=1;break;}
cout<<"Top sticks: ";
int k=0;
for(int i=0;i<n;i++)
if(!flag[i])
a[k++]=i+1;
for(int i=0;i<k-1;i++)
printf("%d, ",a[i]);
printf("%d.\n",a[k-1]);
}
return 0;
}