Angle Beats
平面上给2000个固有点,点坐标范围-1e9~+1e9,给2000个询问,每个询问给个点A,问和给定的2000个固有点能组成多少个直角三角形?
对于给定点A,如果点A当作直角顶点,直接极角排序,对每个固有点判断旋转90°的位置有多少点,累加即可。
如果A不是直角顶点,应以固有的2000个点为原点,对其他1999个固有点和A极角排序,当扫到A时判断垂直方向有多少个固有点。
但是对于每次询问都会有O(n*(nlogn+n))的复杂度,在2000个询问的情况下无疑会TLE。
所以需要以2000个固有点每一个为原点,对剩余点极角排序,遇到询问点时进行处理。可以消除2000个询问带来的影响。
#include
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
static const int maxn = 4010;
static const int INF = 0x3f3f3f3f;
static const int mod = (int)1e9 + 7;
static const double eps = 1e-6;
static const double pi = acos(-1);
void redirect(){
#ifdef LOCAL
freopen("test.txt","r",stdin);
#endif
}
inline int sign(const int& x){return x>0?1:(x==0?0:-1);}
struct point{
int id,x,y;
point(int x,int y){
this->x = x,this->y = y;
}
point(){}
}p[maxn],q[maxn],o;
point operator-(const point& a,const point& b){
return point(a.x-b.x,a.y-b.y);
}
bool operator^ (const point& a,const point& b){
return (1ll*a.x*b.y - 1ll*a.y*b.x) > 0;
}
inline int Quadrant(const point& a){
if(a.x>0 && a.y>=0)return 1;
else if(a.x<=0 && a.y>0)return 2;
else if(a.x<0 && a.y<=0)return 3;
else if(a.x>=0 && a.y<0)return 4;
}
bool operator< (const point& c,const point& d){
point a = c-o,b = d-o;
int qa = Quadrant(a),qb = Quadrant(b);
if(qa != qb)return qa < qb;
return a ^ b;
}
int ans[maxn];
int main(){
redirect();
int n,m,ma;
while(~scanf("%d %d",&n,&m)){
ma = n+m;
memset(ans,0,sizeof(ans));
memset(p,0,sizeof(p));
for(int i = 1;i <= n;i++){
p[i].id = i;
scanf("%d %d",&p[i].x,&p[i].y);
q[i] = p[i];
}
for(int i = n+1;i <= ma;i++){
p[i].id = i;
scanf("%d %d",&p[i].x,&p[i].y);
o = p[i];
sort(p+1,p+1+n);
for(int j = 1;j <= n;j++){
int x = p[j].x - o.x,y = p[j].y - o.y;
point a = point(o.x-y,o.y+x);
ans[i] += upper_bound(p+1,p+1+n,a) - lower_bound(p+1,p+1+n,a);
}
}
for(int i = 1;i <= n;i++){
memcpy(p+1,q+1,sizeof(point)*n);
o = p[i];
swap(p[i],p[n]);
sort(p+1,p+n);
for(int k = n+1;k <= ma;k++){
int x = p[k].x - o.x,y = p[k].y - o.y;
point a = point(o.x-y,o.y+x),b = point(o.x+y,o.y-x);
ans[p[k].id] += upper_bound(p+1,p+n,a) - lower_bound(p+1,p+n,a);
ans[p[k].id] += upper_bound(p+1,p+n,b) - lower_bound(p+1,p+n,b);
}
}
for(int i = n+1;i <= ma;i++)printf("%d\n",ans[i]);
}
return 0;
}
Angel Beats?Angle Beats?
音无结弦之时,天使跃动之心。立于浮华之世,奏响天籁之音。
做出就是金银,做不出就是废铜。