POJ 2318 (叉积) TOYS

题意:

有一个长方形,里面从左到右有n条线段,将矩形分成n+1个格子,编号从左到右为0~n。

端点分别在矩形的上下两条边上,这n条线段互不相交。

现在已知m个点,统计每个格子中点的个数。

分析:

用叉积判断点与线段的相对位置,对于每个点二分查找所在的格子。

 1 #include <cstdio>

 2 #include <cmath>

 3 #include <cstring>

 4 

 5 struct Point

 6 {

 7     int x, y;

 8     Point(int x=0, int y=0):x(x), y(y) {}

 9 };

10 typedef Point Vector;

11 

12 Point read_point()

13 {

14     int x, y;

15     scanf("%d%d", &x, &y);

16     return Point(x, y);

17 }

18 

19 Point operator + (const Point& A, const Point& B)

20 { return Point(A.x+B.x, A.y+B.y); }

21 

22 Point operator - (const Point& A, const Point& B)

23 { return Point(A.x-B.x, A.y-B.y); }

24 

25 int Cross(const Point& A, const Point& B)

26 { return A.x*B.y - A.y*B.x; }

27 

28 const int maxn = 5000 + 10;

29 int up[maxn], down[maxn], ans[maxn];

30 int n, m, kase = 0;

31 Point A0, B0;

32 

33 int binary_search(const Point& P)

34 {

35     int L = 0, R = n;

36     while(L < R)

37     {

38         int mid = L + (R - L + 1) / 2;

39         Point A(down[mid], B0.y), B(up[mid], A0.y);

40         Vector v1 = B - A;

41         Vector v2 = P - A;

42         if(Cross(v1, v2) < 0) L = mid;

43         else R = mid - 1;

44     }

45     return L;

46 }

47 

48 int main()

49 {

50     //freopen("in.txt", "r", stdin);

51 

52     while(scanf("%d", &n) == 1 && n)

53     {

54         memset(ans, 0, sizeof(ans));

55 

56         scanf("%d", &m); A0 = read_point(); B0 = read_point();

57         for(int i = 1; i <= n; ++i) scanf("%d%d", &up[i], &down[i]);

58         for(int i = 0; i < m; ++i)

59         {

60             Point P; P = read_point();

61             int pos = binary_search(P);

62             ans[pos]++;

63         }

64 

65         if(kase++) puts("");

66         for(int i = 0; i <= n; ++i) printf("%d: %d\n", i, ans[i]);

67     }

68 

69     return 0;

70 }
代码君

 

你可能感兴趣的:(poj)