题目链接:115.157.200.87/front/problem?problemId=1056(HNU内网访问)
Problem Description
The ocean can be represented as the first quarter of the Cartesian plane. There are n fish in the ocean. Each fish has its own coordinates. There may be several fish at one point.
There are also m fishermen. Each fisherman has its own x-coordinate. The y-coordinate of each fisherman is equal to 0.
Each fisherman has a fishing rod of length l. Therefore, he can catch a fish at a distance less than or equal to l. The distance between a fisherman in position x and a fish in position (a, b) is |a − x| + b.
Find for each fisherman how many fish he can catch.
Input
The first line contains three integers n, m, and l (1≤n,m≤2⋅105,1≤l≤109) — the number of fish, the number of fishermen, and the length of the fishing rod, respectively.
Each of the next n lines contains two integersxi and yi(1≤xi,yi,≤109) — the fish coordinates.
Next line contains m integers ai (1 ≤ ai ≤ 10^9) — the fishermen coordinates.
Output
For each fisherman, output the number of fish that he can catch, on a separate line.
Sample Input
8 4 4
7 2
3 3
4 5
5 1
2 2
1 4
8 4
9 4
6 1 4 9
Sample Output
2
2
3
2
Note
The picture illustrates for the above example the area on which the third fisherman can catch fish.
题意:
n条鱼,m个渔夫,钓鱼线长l,渔夫的位置是(0,aj),和鱼(xi,yi)的距离是|ai-xi|+yi,问每个渔夫最多能钓到多少条鱼。(要能钓到鱼需要钓鱼线长大于他们间的距离)
题解:
对于鱼(xi,yi),很显然,如果yi大于l那么那个渔夫都钓不上;否则的话,每个鱼在x轴上能被钓到的区间为[xi-l+yi]。转化成一个区间问题:对于每个aj落在多少个区间内。
用left[i]表示第i个可能能被钓上的鱼在x轴上的左边界,right[i]为右边界。从小到大排序后利用二分:
找出第一个右边界大于等于aj的序号lb,说明左边的[0,lb-1]共lb个区间不可能包含aj;
找出第一个左边界大于aj的序号rb,说明右边的[rb,cnt-1]共cnt-rb个区间不可能包含aj;
对于每一个aj,能落的区间个数即是cnt-(cnt-rb)-lb=rb-lb;(cnt为可能被钓上的鱼的个数)
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MAXN=2e5+5; 4 const int MAXM=2e5+5; 5 int Left[MAXN],Right[MAXN]; 6 int a[MAXM]; 7 int read() 8 { 9 int s=1,x=0; 10 char ch=getchar(); 11 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();} 12 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();} 13 return x*s; 14 } 15 int main() 16 { 17 int n=read(),m=read(),l=read(); 18 int xi,yi,cnt=0; 19 for(int i=1;i<=n;++i) 20 { 21 xi=read(),yi=read(); 22 if(yi>l) continue; 23 Left[++cnt]=xi-l+yi; 24 Right[cnt]=xi+l-yi; 25 } 26 sort(Left+1,Left+cnt+1); 27 sort(Right+1,Right+cnt+1); 28 int lb,ub,ai; 29 queue<int> ans; 30 for(int i=1;i<=m;++i) 31 { 32 ai=read(); 33 lb=lower_bound(Right+1,Right+cnt+1,ai)-Right; 34 ub=upper_bound(Left+1,Left+cnt+1,ai)-Left; 35 ans.push(ub-lb); 36 } 37 while(!ans.empty()) 38 { 39 cout<<ans.front()<<"\n"; 40 ans.pop(); 41 } 42 }