(The 12th Blue Bridge Cup Provincial Competition) Test Question C Straight Line (set+Prevention of Loss of Accuracy)

topic:

This problem can directly solve k and b by force, then put k and b into the set as a two-tuple, and finally record the number of elements in the set directly, but one thing to note is that we use floating-point There will be precision loss in the operation, so we should try to avoid using the number after the loss of precision to calculate, that is to say, we cannot use k to bring into the calculation when we solve b, because there will be precision loss in the process of calculating k, so We should use k's calculation expression substitution method to calculate b

For y1=k*x1+b and y2=k*x2+b

We know that k=(y1-b)/x1, b=y2-k*x2, since we have calculated k at the beginning, but the k at this time has a loss of precision, we should not use the previously calculated k Substitute into the following equation again to calculate b, but should use (y1-b)/x1 into the following equation to calculate b, that is, b=(x1y2-y1x2)/(x1-x2), using this equation to It is possible to calculate b with less loss of precision

In order to prevent special cases, it is recommended that you consider the case where the slope is 0 and the slope does not exist separately. This is a good consideration, that is, the interval length of x changes + the interval length of y changes, which can effectively avoid some errors, the following is the code:
 

#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;
}

The result is 40257

Guess you like

Origin blog.csdn.net/AC__dream/article/details/123958806