C1. Power Transmission (Easy Edition)[手把手教截距式]

easy版本其实就是计算直线的解析式…

但我这个计算几何渣渣还是不咋会

暴力枚举两点计算解析式

线 线 这条直线可以和之前的所有斜率不同的直线相交

但这里考虑一个问题,斜率相同但截距不同的也是不同的直线,也要存下来

m a p , , 用map存,键存斜率,值存斜率对应的所有截距

, c , 下面推一下小学数学,其中c表示任意常数,所以正负号不重要

A x + B y + c = 0 y = A B x + c 因为Ax+By+c=0可得y=\frac{-A}{B}x+c

y = k x + c , k = A B y=kx+c,k=\frac{-A}{B}

k = y 2 y 1 x 2 x 1 又因为已知两点求k=\frac{y2-y1}{x2-x1}

A = ( y 2 y 1 ) , B = ( x 2 x 1 ) , C = A x B y 得A=-(y2-y1),B=(x2-x1),C=-Ax-By

这里对应代码中的

int q=x-x2,w=y-y2;
if( q&&w )
{
	int s=gcd(q,w);
	A=w/s,B=q/s;
	if( A<0 )	A=-A,B=-B;//让直线符号统一
}
else if( w==0&&q )	A=0,B=1;//w是0,斜率为0,表达式是和x平行的线,y=()
else if( w&&q==0 )	A=1,B=0;//q是0,斜率不存在,表达式是和y轴平行的线,x=()
A=-A;//A应该是负,见上面的分析
C=-A*x-B*y;
#include <bits/stdc++.h>
using namespace std;
const int maxn=1009;
int X[maxn],Y[maxn],tot,ans,n;
int gcd(int a,int b){
	return b==0?a:gcd(b,a%b);
}
map< pair<int,int>,set<int> >mp;
int main()
{
	cin >> n;
	for(int i=1;i<=n;i++)	cin >> X[i] >> Y[i];
	for(int i=1;i<=n;i++)
	for(int j=i+1;j<=n;j++)
	{
		int x=X[i],y=Y[i],A,B,C;
		int x2=X[j],y2=Y[j];
		int q=x-x2,w=y-y2;
		if( q&&w )
		{
			int s=gcd(q,w);
			A=w/s,B=q/s;//斜率是y/x, 
			if( A<0 )	A=-A,B=-B;
		}
		else if( w==0&&q )	A=0,B=1;
		else if( w&&q==0 )	A=1,B=0;
		A=-A;
		C=-A*x-B*y;
		pair<int,int> sp(A,B);
		if( !mp[sp].count(C) )
		{
			tot++;
			mp[sp].insert(C);
			ans+=(tot-mp[sp].size() );//新加入的直线和所有斜率不同的直线相交 
		}
	}
	cout << ans;
}

猜你喜欢

转载自blog.csdn.net/jziwjxjd/article/details/107758880