试题B 直线

题目链接:https://www.lanqiao.cn/courses/2786/learning/?id=280825

答案:40257

题目解析:

直线分为两部分:平行坐标轴和不平行坐标轴(的直线)

对于平行坐标轴的直线,在结果里加上即可。

对于不平行坐标轴的直线,利用直线的性质:

对于(x1,y1)和(x2,y2),这两点确定的直线y=kx+b,各参数的值为:

k = (y1 - y2) * 1.0 / (x1 - x2) ;(实际操作中需要让 (y1 - y2) 乘上 1.0的目的是使其变为浮点数)

b = y1 * 1.0 - k * x1;

创建一个直线类,根据k和b排序,再根据排序结果进行查重.

注意到,两直线k1,b1和k2,b2为不同直线的充要条件是:

k1 ≠ k2 && b1 ≠ b2

但想在计算机中精确实现上述关系有一定难度,因此结合本题,我们认为:

|a-b|<1e-8 <=> a==b

(本质是因为题目要求的直线中,不同直线k的值或b的值至少相差1e-8以上)

代码:

//#define local
#include<cstdio>
#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath> 
typedef long long ll;
using namespace std;
#define MAXX 20
#define MAXY 21
struct line{
	double k,b;
	line(double k,double b):k(k),b(b){
	}
	bool operator < (const line &t) const{
	if(k!=t.k)
	return k<t.k;
	else
	return b<t.b;
	}
};
//判断double a,b是否相等
bool cheak(double a,double b){
	if(fabs(a-b)<1e-8)
	return true;
	else
	return false;
}
vector<line>q;
int main(){
#ifdef local
freopen("data.in","rb",stdin);
//freopen("data.out","wb",stdout);
#endif
int ans=MAXX+MAXY;
for(int i=0;i<MAXX;++i){
	for(int j=0;j<MAXY;++j){
		for(int w=0;w<MAXX;++w){
			if(w==i)
			continue;
			for(int v=0;v<MAXY;++v){
				if(v==j)
				continue;
				double k=(v-j)*1.0/(w-i);
				double b=j*1.0-k*i;
				q.push_back(line(k,b));
			}
		} 
	}
}
sort(q.begin(),q.end());
ans++;
for(int i=1;i<q.size();++i){
	if(cheak(q[i].k,q[i-1].k)&&cheak(q[i].b,q[i-1].b))
	continue;
	++ans;
}
cout<<ans;
return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值