- 题意: 在二维平面给出很多棍子,求在最上面的棍子(不被覆盖)
- 思路: 从前向后枚举线段是否跟后面线段有交点即可
#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的符号判断点对于线段的相对位置: 大于零右侧,小于零左侧,等于零在线段上