POJ 2653 Pick-up sticks(线段相交)

题目链接

题意 : 把每根棍往地上扔,找出最后在上面的棍,也就是说找出所有的没有别的棍子压在它的上面的棍子。

思路 : 对于每根棍子,压在他上面的棍子一定是在它之后扔的棍子,所以在找的时候只要找它之后的线段是否与他相交即可。

 1 //2653

 2 #include <stdio.h>

 3 #include <iostream>

 4 #include <math.h>

 5 #include <string.h>

 6 

 7 using namespace std ;

 8 

 9 struct point

10 {

11     double x,y ;

12 }p[200100];

13 struct line

14 {

15     point a,b ;

16 }L[101000];

17 int ans[1100] ;

18 

19 double multi(point a,point b,point c)

20 {

21     return ((a.x-c.x) * (b.y-c.y) - (b.x-c.x)*(a.y-c.y)) ;

22 }

23 bool intersect(point a,point b,point c,point d)//非规范相交

24 {

25     if(max(a.x,b.x) < min(c.x,d.x) || max(a.y,b.y) < min(c.y,d.y) || max(c.x,d.x) < min(a.x,b.x) || max(c.y,d.y) < min(a.y,b.y))

26         return false ;

27     if(multi(c,b,a) * multi(b,d,a) < 0 || multi(a,d,c)*multi(d,b,c) < 0) return false ;

28     return true ;

29 }

30 int main()

31 {

32     int n ;

33     while(~scanf("%d",&n))

34     {

35         if(n == 0)  break ;

36         for(int i = 1 ; i <= n ; i++)

37             scanf("%lf %lf %lf %lf",&L[i].a.x,&L[i].a.y,&L[i].b.x,&L[i].b.y) ;

38         int cnt = 0 ;

39         for(int i = 1 ; i < n ; i++)

40         {

41             bool flag = true ;

42             for(int j = i+1 ;j <= n ; j++)

43             {

44                 if(intersect(L[i].a,L[i].b,L[j].a,L[j].b))

45                 {

46                     flag = false ;

47                     break ;

48                 }

49             }

50             if(flag) ans[cnt ++] = i ;

51         }

52         printf("Top sticks: ") ;

53         for(int i = 0 ; i < cnt ; i++)

54         {

55             printf("%d, ",ans[i]) ;

56         }

57         printf("%d.\n",n) ;

58     }

59     return 0 ;

60 }
View Code

 

你可能感兴趣的:(poj)