题目链接:http://poj.org/problem?id=2653
题意:给你n根木棍,问在最上面的有哪些?
思路:运用叉积判断线段是否相交。在比较的时候,一定要注意顺序。否则有可能TLE。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
struct Point {
double x, y;
};
const int MAXN = 100110;
Point point[2*MAXN];
int set[MAXN];
int cnt[1010];
int direction(Point p1, Point p2, Point p3) {
//(p3-p1)x(p2-p1)
return ((p3.x - p1.x)*(p2.y - p1.y)) - ((p3.y - p1.y)*(p2.x - p1.x));
}
int interact(Point p1, Point p2, Point p3, Point p4) {
int d1 = direction(p1, p2, p3);
int d2 = direction(p1, p2, p4);
int d3 = direction(p3, p4, p1);
int d4 = direction(p3, p4, p2);
if(((d1<0 && d2>0) || (d1>0 && d2<0)) && ((d3>0 && d4<0) || (d3<0 && d4>0))) return 1;
return 0;
}
int main() {
int t, i, j;
freopen("/home/lsy/Desktop/2.txt", "r", stdin);
while(cin >> t) {
if(t==0) break;
//memset(set, 0, sizeof(set));
for(i=0; i<2*t; i+=2) {
scanf("%lf%lf%lf%lf", &point[i].x,&point[i].y,&point[i+1].x,&point[i+1].y);
set[i/2] = 1;
}
/*
我第一次是一边输入,一边拿这个线段和前面所有在最上面的比较。TLE。
看了discuss后,改成下面这样.
*/
for(i=0; i<2*t; i+=2) {
for(j=i+2; j<2*t; j+=2) {
if(interact(point[i], point[i+1], point[j], point[j+1])) {
set[i/2] = 0;
break;
}
}
}
j = 0;
for(i=0; i<t; i++)
if(set[i]) cnt[j++] = i+1;
printf("Top sticks: ");
for(i=0; i<j; i++) {
if(i != j-1) printf("%d, ", cnt[i]);
else printf("%d.\n", cnt[i]);
}
}
return 0;
}