题目链接
题意
依次扔(n)根小棒,输出没有被压着的小棒的编号。
思路
对每根小棒,判断它和之后扔的小棒有没有交点。一旦有,就将其排除掉。
虽然算法是(O(n^2)的),但是数据水呀~
注意:如果对于每根小棒去判断它有没有压着前面的小棒,将前面被压着的小棒排除掉,这种写法会(T)
Code
#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#define inf 1e200
#define eps 1e-6
#define maxn 100010
using namespace std;
typedef long long LL;
struct Point {
double x, y;
Point(double _x=0, double _y=0) : x(_x), y(_y) {}
Point operator + (const Point& b) const {
return Point(x+b.x, y+b.y);
}
Point operator - (const Point& b) const {
return Point(x-b.x, y-b.y);
}
double operator * (const Point& b) const {
return x*b.x + y*b.y;
}
double operator ^ (const Point& b) const {
return x*b.y - y*b.x;
}
};
struct Seg {
Point s, e;
Seg(Point _s, Point _e) : s(_s), e(_e) {}
Seg() {}
}seg[maxn];
int sgn(double x) {
if (fabs(x) < eps) return 0;
if (x > 0) return 1;
return -1;
}
double xmult(Point s, Point e, Point b) {
return (s-b) ^ (e-b);
}
bool intersect(Seg u, Seg v) {
return (max(u.s.x,u.e.x) >= min(v.s.x,v.e.x)) &&
(max(v.s.x,v.e.x) >= min(u.s.x,u.e.x)) &&
(max(u.s.y,u.e.y) >= min(v.s.y,v.e.y)) &&
(max(v.s.y,v.e.y) >= min(u.s.y,u.e.y)) &&
(sgn(xmult(v.s,u.e,u.s)) * sgn(xmult(u.e,v.e,u.s)) >= 0) &&
(sgn(xmult(u.s,v.e,v.s)) * sgn(xmult(v.e,u.e,v.s)) >= 0);
}
int n, ans[1010];
bool out[maxn];
void work() {
memset(out, 0, sizeof out);
for (int i = 1; i <= n; ++i) {
double x1,y1,x2,y2;
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
seg[i] = Seg(Point(x1, y1), Point(x2, y2));
}
for (int i = 1; i <= n; ++i) {
for (int j = i+1; j <= n; ++j) {
if (intersect(seg[i], seg[j])) { out[i] = true; break; }
}
}
int tot = 0;
for (int i = 1; i <= n; ++i) if (!out[i]) ans[tot++] = i;
printf("Top sticks:");
for (int i = 0; i < tot-1; ++i) printf(" %d,", ans[i]); printf(" %d.
", ans[tot-1]);
}
int main() {
while (scanf("%d", &n) != EOF && n) work();
return 0;
}