POJ 1511 Pick-up sticks(线段相交)
- 题意: 在二维平面给出很多棍子,求在最上面的棍子(不被覆盖)
- 思路: 从前向后枚举线段是否跟后面线段有交点即可
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <stdlib.h>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define ll long long
#define FOR(i,l,r) for(int i = l ; i <= r ;++i )
#define inf 1<<30
#define eps (1e-9)
#define ALL(T) T.begin(),T.end()
#define lson(i) i<<1
#define rson(i) (i<<1|1)
using namespace std;
typedef pair<int,int> pii;
const int maxn = 100010;
int sgn(double a){
if(fabs(a)<eps) return 0;
if(a>0) return 1;
return -1;
}
struct point{
double x,y;
point(){}
point(double _x,double _y):x(_x),y(_y){}
void input(){
scanf("%lf%lf",&x,&y);
}
point operator - (point b){
return point(x-b.x,y-b.y);
}
};
double sqr(double a){return a*a;}
double det(point a,point b){ //叉乘
return a.x * b.y - a.y * b.x;
}
struct line{
point a,b;
line(){}
line(point _a,point _b):a(_a),b(_b){}
};
int n;
int vis[maxn];
int check(line la,line lb){
// 端点均在线段两边,即为有交点
if(sgn(det(la.a-lb.a,la.b-lb.a))*sgn(det(la.a-lb.b,la.b-lb.b))==-1
&& sgn(det(lb.a-la.a,lb.b-la.a))*sgn(det(lb.a-la.b,lb.b-la.b))==-1)
return true;
return false;
}
vector<line> ve;
void solve(){
ve.clear();
memset(vis,0,sizeof vis);
point a,b;
FOR(i,1,n){
scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y);
ve.push_back(line(a,b));
}
FOR(i,0,n-1){
FOR(j,i+1,n-1){
// printf("%lf %lf ",ve[i].a.x,ve[i].a.y);
if(check(ve[i],ve[j])){
vis[i] = 1;
break;
}
}
}
printf("Top sticks:");
int first = 1;
FOR(i,0,n-1){
if(!vis[i]){
if(!first){
printf(",");
}
printf(" %d",i+1);
first = 0;
}
}
printf(".\n");
}
int main(){
while(scanf("%d",&n) && n!=0){
solve();
}
return 0;
}
我们可以通过det的符号判断点对于线段的相对位置: 大于零右侧,小于零左侧,等于零在线段上