Power Transmission (Easy Edition)
题意读完,就知道要处理出n*(n-1)/2条直线了。那么关键在于这条直线用什么样的方式存储起来呢?我用的是点斜式,存储斜率k和截距b,但是很遗憾,WA在了test15.
看了题解,正确地存储方式是用直线的一般式Ax+By+C=0,好的我们现在存储三个信息,这里有一个细节需要注意,就是A和B这两个信息是跟斜率有关的,k=-A/B,所以,A和B一定要除以他们的最大公约数,而且要表示符号的一致性,才不会使斜率相等的直线误认为不等。
这样,我们用set去除了完全相同的直线之后,只要知道我们剩余的直线集里面有多少斜率相等即可,答案就是E*(E-1)/2-cnt
typedef long long int ll;
const int maxn=5e1+5;
const double INF=1e9+5;
struct node{
ll x1,x2,x3;
bool operator<(const node& a)const{
return x1<a.x1||(x1==a.x1&&x2<a.x2)||(x1==a.x1&&x2==a.x2&&x3<a.x3);
}
};
node a[maxn];
set<node>q;
node f(node a,node b){
node t;
t.x1=b.x2-a.x2;
t.x2=a.x1-b.x1;
ll d=__gcd(t.x1,t.x2);t.x1/=d;t.x2/=d;
if(t.x1<0||(t.x1==0&&t.x2<0)){
t.x1*=-1;t.x2*=-1;
}
t.x3=-(t.x1*a.x1+t.x2*a.x2);
return t;
}
int main(){
FIN
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].x1>>a[i].x2;
}
for(int i=1;i<n;i++){
for(int j=i+1;j<=n;j++){
q.insert(f(a[i],a[j]));
}
}
ll cnt=0;
for(set<node>::iterator it=q.begin();it!=q.end();it++){
for(set<node>::iterator it2=it;it2!=q.end();it2++){
if(it->x1==it2->x1&&it->x2==it2->x2&&it->x3!=it2->x3)cnt++;
}
}
ll m=q.size();
cout<<(m-1)*m/2-cnt;
}