CCPC秦皇岛gym102361A. Angle Beats

Posted Jozky86

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CCPC秦皇岛gym102361A. Angle Beats相关的知识,希望对你有一定的参考价值。

CCPC秦皇岛gym102361A. Angle Beats

题意:

给你n个点的坐标,现在有q次询问,每次询问给你一个坐标,问这个坐标可以与给定的n个点组成多少个不同的直角三角形
n<=2000,q<=2000

题解:

正解貌似是用极角排序后尺取得到答案,但我看很多人有更简便的方法
对于每次询问,我们可以分别考虑被询问点是直角点还是非直角点
如果是直角点,我们可以先将n个点与被询问点的斜率存下来,然后再循环n个点,看有多少个点是可以构成直线(即斜率乘积为-1)
如果是非直角点,我们可以直接 n 2 n^2 n2枚举n个点,然后判断是否可以构成直角
这个题原理很简单,细节很多,首先斜率直接存很麻烦,我们存横纵坐标。其次map跑的很慢,因此加map的值时可以先判断map中是否存有对应的参数,否则会T
详细见代码

代码:

#include <bits/stdc++.h>
#include <unordered_map>
#define debug(a, b) printf("%s = %d\\n", a, b);
using namespace std;
bool Handsome;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
clock_t startTime, endTime;
//Fe~Jozky
const ll INF_ll= 1e18;
const int INF_int= 0x3f3f3f3f;
void read();
template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar)

    x= 0;
    char c= getchar();
    bool flag= 0;
    while (c < '0' || c > '9')
        flag|= (c == '-'), c= getchar();
    while (c >= '0' && c <= '9')
        x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();
    if (flag)
        x= -x;
    read(Ar...);

template <typename T> inline void write(T x)

    if (x < 0) 
        x= ~(x - 1);
        putchar('-');
    
    if (x > 9)
        write(x / 10);
    putchar(x % 10 + '0');

void rd_test(bool &Most)

#ifdef ONLINE_JUDGE
#else
	printf("%.2lfMB\\n",(&Most-&Handsome)/1024.0/1024.0);
    startTime = clock ();
    freopen("data.in", "r", stdin);
#endif

void Time_test()

#ifdef ONLINE_JUDGE
#else
    endTime= clock();
    printf("\\nRun Time:%lfs\\n", (double)(endTime - startTime) / CLOCKS_PER_SEC);
#endif

const int maxn=2e4+9;
bool Most;
struct Point
	ll x,y;
	Point()
	Point(ll _x,ll _y)
		x=_x;
		y=_y;
	
	void input()
		read(x,y);
	
	Point update()const
		if(x<0||(x==0&&y<0))
			return Point(-x,-y);
		else 
			return Point(x,y);
	
	bool operator<(const Point &b)const
		Point A=update(),B=b.update(); 
		return A.x*B.y<A.y*B.x;
	
	Point operator-(const Point &b)const
		return Point(x-b.x,y-b.y); 
	 
point[maxn];
int ans[maxn];
map<Point,int>mp;
vector<Point>vec;
int main()

    rd_test(Most);
	int n,q;
	read(n,q);
	for(int i=1;i<=n;i++)
		point[i].input();
	for(int i=0;i<q;i++)
		mp.clear();
		Point q;
		q.input();
		vec.push_back(q);
		for(int j=1;j<=n;j++)
			mp[point[j]-q]++;
		for(auto it:mp)
			Point tmp(-it.first.y,it.first.x);
			if(mp.count(tmp))
				ans[i]+=mp[tmp]*it.second;
		
		ans[i]/=2;
	
	for(int i=1;i<=n;i++)//n个点分别为直角 
		mp.clear();
		for(int j=1;j<=n;j++)
			if(i==j)continue;
			mp[point[j]-point[i]]++;
		
		for(int j=0;j<q;j++)
			Point tmp=vec[j]-point[i];
			tmp=Point(-tmp.y,tmp.x);
			if(mp.count(tmp))
				ans[j]+=mp[tmp];
		
	
	for(int i=0;i<q;i++)
		printf("%d\\n",ans[i]);
//		cout<<ans[i]<<endl; 
    //Time_test();







以上是关于CCPC秦皇岛gym102361A. Angle Beats的主要内容,如果未能解决你的问题,请参考以下文章

CCPC秦皇岛gym102361A. Angle Beats

Codeforces Gym 102361A Angle Beats CCPC2019秦皇岛A题 题解

[CCPC2019秦皇岛] E. Escape

[CCPC2019秦皇岛] F. Forest Program

Angle Beats Gym - 102361A(计算几何)

Gym102361A Angle Beats(直角三角形 计算几何)题解