【问题描述】
小 Q 对计算几何有着浓厚的兴趣。他经常对着平面直角坐标系发呆,思考
一些有趣的问题。今天,他想到了一个十分有意思的题目:
首先,小 Q 会在x轴正半轴和y轴正半轴分别挑选??个点。随后,他将x轴的
点与y轴的点一一连接,形成??条线段,并保证任意两条线段不相交。小 Q 确定
这种连接方式有且仅有一种。最后,小 Q 会给出m个询问。对于每个询问,将会
给定一个点P(Px ,Py),请回答线段 OP 与m条线段会产生多少个交点?
小 Q 找到了正在钻研数据结构的你,希望你可以帮他解决这道难题。
【输入格式】
第1一个正整数n,表示线段的数量;
第2行包含n个正整数表示小Q在x轴选取的点的横坐标 第3行包含n个正整数,表示小 Q 在y轴选取的点的纵坐标;
第 4 行包含一个正整数m,表示询问数量;
随后??行,每行包含两个正整数Px ,Py ,表示询问中给定的点的横、纵坐标。
【输出格式】
共??行,每行包含一个非负整数,表示你对这条询问给出的答案。
【样例输入】
3
4 5 3
3 5 4
2
1 1
3 3
【样例输出】
0
3
【样例解释】
然后塔里啥都没有。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cctype> 5 #include<iostream> 6 #include<algorithm> 7 using namespace std; 8 const int BUF_SIZE = 30; 9 char buf[BUF_SIZE], *buf_s = buf, *buf_t = buf + 1; 10 const int maxn = 200010; 11 long long x[maxn], y[maxn]; 12 int n, m; 13 bool toLeft(int num, long long _x, long long _y) { 14 return (x[num] * _y + y[num] * (_x - x[num])) >= 0; 15 } 16 int getcnt(long long _x, long long _y) { 17 int l = 0, r = n + 1; 18 while (l < r - 1) { 19 int mid = (l + r) >> 1; 20 if (!mid) break; 21 if (toLeft(mid, _x, _y)) l = mid; 22 else r = mid; 23 } 24 return l; 25 } 26 int main() { 27 freopen("hahaha.in","r",stdin); 28 freopen("hahaha.out","w",stdout); 29 scanf("%d",&n); 30 for (int i = 1; i <= n; ++ i) 31 scanf("%d",&x[i]); 32 for (int i = 1; i <= n; ++ i) 33 scanf("%d",&y[i]); 34 sort(x + 1, x + n + 1); 35 sort(y + 1, y + n + 1); 36 scanf("%d",&m); 37 while (m --) { 38 int _x, _y; 39 scanf("%d%d",&_x,&_y); 40 printf("%d\n", getcnt(_x, _y)); 41 } 42 return 0; 43 }
思路:数学判断+二分答案
时间: 2024-11-05 06:13:00