明显不能暴力枚举两条直线。我们考虑怎样的情况会使得两条直线相交于圆内。如图:
只有这种情况:两条线与圆的4个交点相间排列。
故我们求出每条直线与圆的交点,把圆拉成一条线段,然后在线段上求交错的线段对数,树状数组+离散化即可。
/*************************************************************
Problem: bzoj 1573 [Usaco2009 Open]牛绣花cowemb
User: fengyuan
Language: C++
Result: Accepted
Time: 204 ms
Memory: 2788 kb
Submit_Time: 2017-10-09 17:45:14
*************************************************************/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define Pair pair<double, double>
#define mp make_pair
#define F first
#define S second
using namespace std;
const int N = 50010;
int n, cnt = 0, ans = 0;
double r, X1, X2, Y1, Y2, tmp, A, B, C, a, b, c, delta, L, R;
double inter[N<<1];
int T[N<<1];
Pair p[N];
inline void add(int k){ for (; k < N<<1; k += k&-k) T[k] ++; }
inline int getSum(int k){ int ret = 0; for (; k; k -= k&-k) ret += T[k]; return ret; }
inline double getPos(double x, double y){ if (y < 0) return -(r+x); else return r+x; }
int main()
{
scanf("%d%lf", &n, &r);
// x^2+y^2=r^2
// ax+by+c=0
for (int i = 1; i <= n; i ++){
scanf("%lf%lf%lf", &a, &b, &c);
bool mark = 0;
if (a == 0 || b == 0){
if (a == 0){
Y1 = Y2 = -c/b;
tmp = r*r-Y1*Y1;
if (tmp < 0) mark = 1;
else{ X1 = sqrt(tmp); X2 = -sqrt(tmp); }
} else{
X1 = X2 = -c/a;
tmp = r*r-X1*X1;
if (tmp < 0) mark = 1;
else{ Y1 = sqrt(tmp); Y2 = -sqrt(tmp); }
}
} else{
A = a*a+b*b; B = 2*b*c; C = c*c-a*a*r*r;
delta = B*B-4*A*C;
if (delta < 0) mark = 1;
else{
Y1 = (-B+sqrt(delta))/(2*A); X1 = (-c-b*Y1)/a;
Y2 = (-B-sqrt(delta))/(2*A); X2 = (-c-b*Y2)/a;
}
}
if (mark) continue;
L = getPos(X1, Y1); R = getPos(X2, Y2);
if (L > R) swap(L, R); p[++ cnt] = mp(L, R);
inter[cnt*2-1] = L; inter[cnt*2] = R;
}
sort(inter+1, inter+1+2*cnt);
sort(p+1, p+1+cnt);
for (int i = 1; i <= cnt; i ++){
int left = lower_bound(inter+1, inter+1+2*cnt, p[i].F) - inter;
int right = lower_bound(inter+1, inter+1+2*cnt, p[i].S) - inter;
ans += getSum(right) - getSum(left-1); add(right);
}
printf("%d\n", ans);
return 0;
}

本文介绍了一种高效算法,用于解决给定多条直线与一圆相交时,找出所有相交于圆内的直线对。通过计算每条直线与圆的交点,并利用树状数组和离散化技术来统计相交对数。

1173

被折叠的 条评论
为什么被折叠?



