题意:
有一个长方形,里面从左到右有n条线段,将矩形分成n+1个格子,编号从左到右为0~n。
端点分别在矩形的上下两条边上,这n条线段互不相交。
现在已知m个点,统计每个格子中点的个数。
分析:
用叉积判断点与线段的相对位置,对于每个点二分查找所在的格子。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 ", i, ans[i]); 67 } 68 69 return 0; 70 }