2018.07.03 POJ 2653 Pick-up sticks(简单计算几何)

时间:2021-08-17 08:24:31

Pick-up sticks

Time Limit: 3000MS Memory Limit: 65536K

2018.07.03 POJ 2653 Pick-up sticks(简单计算几何)

Description

Stan has n sticks of various length. He throws them one at a time on the floor in a random way. After finishing throwing, Stan tries to find the top sticks, that is these sticks such that there is no stick on top of them. Stan has noticed that the last thrown stick is always on top but he wants to know all the sticks that are on top. Stan sticks are very, very thin such that their thickness can be neglected.

Input

Input consists of a number of cases. The data for each case start with 1 <= n <= 100000, the number of sticks for this case. The following n lines contain four numbers each, these numbers are the planar coordinates of the endpoints of one stick. The sticks are listed in the order in which Stan has thrown them. You may assume that there are no more than 1000 top sticks. The input is ended by the case with n=0. This case should not be processed.

Output

For each input case, print one line of output listing the top sticks in the format given in the sample. The top sticks should be listed in order in which they were thrown.

The picture to the right below illustrates the first case from input.

Sample Input

5

1 1 4 2

2 3 3 1

1 -2.0 8 4

1 4 8 2

3 3 6 -2.0

3

0 0 1 1

1 0 2 1

2 0 3 1

0

Sample Output

Top sticks: 2, 4, 5.

Top sticks: 1, 2, 3.

Hint

Huge input,scanf is recommended.

Source

Waterloo local 2005.09.17

这道题的数据范围是n≤100000" role="presentation" style="position: relative;">n≤100000n≤100000,其实我也很好奇我是怎么用O(Tn2)" role="presentation" style="position: relative;">O(Tn2)O(Tn2)的算法跑过去的,这道题的思路很简单,照着提议模拟一边就可以了,对于每一条线段,我们判断在它之后的线段有没有与它相交的,如果有就打上标记,没有就不打标记,最后把所有没打标记的线段输出就可以了。

代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100005
using namespace std;
struct pot{double x,y;};
struct line{pot a,b;}l[N];
bool vis[N];
inline double cross(pot a,pot b,pot c){return (a.x-c.x)*(b.y-c.y)-(a.y-c.y)*(b.x-c.x);}
inline bool across(line m,line n){
    if(cross(m.a,n.b,n.a)*cross(m.b,n.b,n.a)<0&&cross(n.a,m.b,m.a)*cross(n.b,m.b,m.a)<0)return true;
    return false;
}
int n;
int main(){
    while(scanf("%d",&n)==1){
        if(n==0)break;
        for(int i=0;i<n;++i)scanf("%lf%lf%lf%lf",&l[i].a.x,&l[i].a.y,&l[i].b.x,&l[i].b.y);
        memset(vis,false,sizeof(vis));
        for(int i=0;i<n;++i){
            if(vis[i])continue;
            for(int j=i+1;j<n;++j){
                if(across(l[i],l[j])){
                    vis[i]=true;
                    break;
                }
            }
        }
        bool f=false;
        printf("Top sticks:");
        for(int i=0;i<n;++i){
            if(!vis[i]){
                if(!f){printf(" %d",i+1),f=true;}
                else printf(", %d",i+1);
            }
        }
        puts(".");
    }
    return 0;
}