隐藏
「bsoj5087」计算几何 - 二分 | Bill Yang's Blog

路终会有尽头,但视野总能看到更远的地方。

0%

「bsoj5087」计算几何 - 二分

题目大意

花花对计算几何有着浓厚的兴趣。他经常对着平面直角坐标系发呆,思考一些有趣的问题。今天,他想到了一个十分有意思的题目:
首先,花花会在$x$轴正半轴和$y$轴正半轴分别挑选$n$个点。随后,他将$x$轴的点与$y$轴的点一一连接,形成$n$条线段,并保证任意两条线段不相交。花花确定这种连接方式有且仅有一种。最后,花花会给出$m$个询问。对于每个询问,将会给定一个点$P(x_p,y_p)$,问线段$OP$($O$为坐标原点)与$n$条线段会产生多少个交点?


题目分析

根据题目要求,需要分别对$x,y$排序。
排完序后不难发现问题具有单调性,因此可以二分得到一条线段,判断这条线段是否与$OP$相交,最后即可得到交点个数。


代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
inline const int Get_Int() {
int num=0,bj=1;
char x=getchar();
while(x<'0'||x>'9') {
if(x=='-')bj=-1;
x=getchar();
}
while(x>='0'&&x<='9') {
num=num*10+x-'0';
x=getchar();
}
return num*bj;
}
int n,m,a[100005],b[100005];
bool Check(int num,int x,int y) {
return (long long)-b[num]*x+(long long)b[num]*a[num]<=(long long)y*a[num];
}
int main() {
n=Get_Int();
for(int i=1; i<=n; i++)a[i]=Get_Int();
for(int i=1; i<=n; i++)b[i]=Get_Int();
sort(a+1,a+n+1);
sort(b+1,b+n+1);
m=Get_Int();
for(int i=1; i<=m; i++) {
int x=Get_Int(),y=Get_Int();
int Left=1,Right=n;
while(Left<=Right) {
int mid=(Left+Right)>>1;
if(Check(mid,x,y))Left=mid+1;
else Right=mid-1;
}
printf("%d\n",Right);
}
return 0;
}
姥爷们赏瓶冰阔落吧~