[BalkanOI 2007] Point
给了n个三维空间上的点,求出有多少条至少包含三点的直线。
因为n的上界为1000,所以允许 \(O(n^2)\) 的算法。
我们可以枚举两个点,记录这条直线。
然后用一个map存储共线的数量然后统计答案就行了。
相当没难度
#include<bits/stdc++.h>
#define gcd __gcd
using namespace std;
struct node{
int x,y,z;
friend bool operator <(node a,node b){return a.x^b.x?a.x<b.x:a.y^b.y?a.y<b.y:a.z<b.z;}
friend bool operator >(node a,node b){return a.x^b.x?a.x>b.x:a.y^b.y?a.y>b.y:a.z>b.z;}
}a[1001];
void calc(int &dx,int &dy,int &dz) {
int g=gcd(abs(dx),gcd(abs(dy),abs(dz)));
if(!g)return;
dx/=g,dy/=g,dz/=g;
if(dx<0)dx=-dx,dy=-dy,dz=-dz;
else if(!dx){
if(dy<0)dy=-dy,dz=-dz;
else if(!dy)if(dz<0)dz=-dz;
}
}
int n,ans;
map<node,pair<int,int>>mp;
int main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i].x>>a[i].y>>a[i].z;
for(int i=1;i<=n;i++){
mp.clear();
for(int j=1;j<=n;j++){
if(i==j)continue;
int dx=a[j].x-a[i].x;
int dy=a[j].y-a[i].y;
int dz=a[j].z-a[i].z;
if(!dx&&!dy&&!dz)continue;
calc(dx,dy,dz);
node t={dx,dy,dz};
if(mp.find(t)==mp.end())mp[t]=make_pair(1,j);
else{
mp[t].first++;
if(j<mp[t].second)mp[t].second=j;
}
}
for(auto &t:mp)if(t.second.first>1)if(t.second.second>i)ans++;
}
cout<<ans;
return 0;
}

浙公网安备 33010602011771号