(第十二届蓝桥杯省赛)试题C直线(set+防止精度损失)

题目:

这道题目直接暴力求解k和b就行,然后把k和b当成一个二元组放入set中,最后直接记录一下集合中元素个数即可,但是有一点需要注意的是因为我们用浮点运算会有精度损失,所以我们应该尽量避免用精度损失后的数再去进行计算,也就是说,我们求解b时不能用k去带入计算,因为计算k的过程中会有精度损失,所以我们应该用k的计算表达式代入方法去计算b

对于y1=k*x1+b和y2=k*x2+b

我们知道k=(y1-b)/x1,b=y2-k*x2,由于我们一开始已经计算出来了k,但是此时的k是有精度损失的,我们不应该用前面计算过的k再次代入后面等式去计算b,而是应该用(y1-b)/x1代入后面的等式去计算b,也就是b=(x1y2-y1x2)/(x1-x2),利用这个等式就可以计算出来精度损失较少的b

为了防止特殊情况,建议大家单独考虑斜率为0和斜率不存在的情况,这个很好考虑,就是x变化的区间长度+y变化的区间长度,这样可以有效避免一些错误,下面是代码:
 

#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<map>
#include<cmath>
#include<queue>
#include<set>
using namespace std;
typedef pair<double,double>PII;
int main()
{
	set<PII>p;
	for(int i=0;i<20;i++)
	for(int j=0;j<21;j++)
	for(int k=0;k<20;k++)
	for(int l=0;l<21;l++)
	{
		if(i==k||j==l) continue;
		double kk=1.0*(l-j)/(k-i);
		double b=1.0*(i*l-j*k)/(i-k);
		p.insert({kk,b});
	}
	cout<<p.size()+41;
	return 0;
}

结果是40257

猜你喜欢

转载自blog.csdn.net/AC__dream/article/details/123958806
今日推荐