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秦皇岛] F. Forest Program