POJ 2653 Pick-up sticks(判斷線段相交)

題意:按順序扔一些木棒(n < 100001),問最後在最上面的木棒(m < 1001)。

這題能過完全是因爲數據弱。

至少我的算法是 O(n * m) 級別或者以上的。。。

本來不敢寫,覺得會TLE,但是看到網上差不多的算法也過了,於是交了結果 1A 。。。只能說數據太水。。。

就當檢驗線段交的模板了。。。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

typedef struct point {
    double x;
    double y;
}point;

typedef struct v {
    point start;
    point end;
}v;

const double eps = 1e-8;

double multi(point p1, point p2, point p0)  //used for Across
{
    return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}

int Across(v v1, v v2)
{
    if(max(v1.start.x,v1.end.x) >= min(v2.start.x, v2.end.x) &&
       max(v2.start.x,v2.end.x) >= min(v1.start.x, v1.end.x) &&
       max(v1.start.y,v1.end.y) >= min(v2.start.y, v2.end.y) &&
       multi(v2.start, v1.end, v1.start) * multi(v1.end, v2.end, v1.start) > 0 &&
       multi(v1.start, v2.end, v2.start) * multi(v2.end, v1.end, v2.start) > 0)
        return 1;
    else
        return 0;
}

const int maxn = 100010;
point seg[maxn][2];
int top[maxn];

int main()
{
    int n;

    while(scanf("%d", &n) && n) {
        int tcnt = 0;
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < 2; j++)
                scanf("%lf%lf", &seg[i][j].x, &seg[i][j].y);
            bool over = false;
            v v1, v2;
            v2.start = seg[i][0];
            v2.end = seg[i][1];
            for(int j = 0; j < tcnt; j++) {
                int cur = top[j];
                v1.start = seg[cur][0];
                v1.end = seg[cur][1];
                if(Across(v1, v2)) {
                    if(!over) {
                        top[j] = i;
                        over = true;
                    }
                    else {
                        for(int k = j; k < tcnt - 1; k++)
                            top[k] = top[k+1];
                        j--;
                        tcnt--;
                    }
                }
            }
            if(!over) {
                top[tcnt] = i;
                tcnt++;
            }
        }
        sort(top, top+tcnt);
        printf("Top sticks: ");
        bool first = true;
        for(int i = 0; i < tcnt; i++) {
            if(i == 0 || top[i] != top[i-1]) {
                if(first)
                    first = false;
                else
                    printf(", ");
                printf("%d", top[i] + 1);
            }
        }
        printf(".\n");
    }

    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章