蓝桥杯 直线


#include
using namespace std;

setdouble, double>> s;
vectorint, int> > v;

int res;

int main()
{
    for (int i = 0;i < 20;i ++)
    {
        for (int j = 0;j < 21;j ++)
        {
            v.push_back({i, j});
        }
    }
    for (int i = 0;i < v.size() - 1;i ++)
    {
        for (int j = i + 1;j < v.size();j ++)
        {
            if (v[i].first == v[j].first) continue;
            double x1 = 1.0*v[i].first, x2 = 1.0*v[j].first;
            double y1 = 1.0*v[i].second, y2 = 1.0*v[j].second;
            double k = (y2-y1)*1.0/(x2-x1);
            double b = (y1*x2-y2*x1)*1.0/(x2-x1);
            // double b = y2-(y2-y1)*1.0/(x2-x1)*x2;
            s.insert({k, b}); 
        }
    }
    cout << (s.size() + 20); // 答案:40257
    
    return 0;
}

蓝桥杯 直线 

已知两点带入 y=kx+b 中求b时,应该用两式消去 kx1x2 的办法求b的表达式,不应该直接带入一点的坐标求b,否则会有精度问题。

#include 
#include 
#include 
#include <set>
using namespace std;
typedef pair<int, int> P;
typedef pairint, int>, pair<int, int>> PP; 
setint, int>, pair<int, int>>> Set; //构造一个set,里面能放两个pair类型。
int main() {
    for (int x1 = 0; x1 < 20; x1++) {
        for (int y1 = 0; y1 < 21; y1++) {
            for (int x2 = 0; x2 < 20; x2++) {
                for (int y2 = 0; y2 < 21; y2++) {
                    if (x1 == x2 && y1 == y2)
                        continue;
                    if (x1 != x2 && y1 != y2) {     //避免斜率不存在的情况,和平行的情况。
                        int k1 = y2 - y1, k1f = 0;  // K的分子 kf1记录k1的正负,我们总想把符号放到分子上
                        if (k1 < 0) //记录是不是负数
                            k1f = 1;
                        int k2 = x2 - x1, k2f = 0;  // K的分母
                        if (k2 < 0)
                            k2f = 1;
                        int c = __gcd(abs(k1), abs(k2));

                        k1 /= c;  //化简
                        k2 /= c;

                        int b1 = y1 * (x2 - x1) - x1 * (y2 - y1), b1f = 0;  //计算b的分子和分母,下面的过程和上面是一样的,
                        if (b1 < 0)
                            b1f = 1;
                        int b2 = x2 - x1, b2f = 0;
                        if (b2 < 0)
                            b2f = 1;
                        c = __gcd(abs(b1), abs(b2));

                        b1 /= c;
                        b2 /= c;
                        // cout << pow(-1, k1f + k2f) * abs(k1) << "/" << abs(k2) << " " << pow(-1, b1f + b2f) * abs(b1) << "/" << abs(b2) << endl;
                        Set.insert({{pow(-1, k1f + k2f) * abs(k1), abs(k2)}, {pow(-1, b1f + b2f) * abs(b1), abs(b2)}});//把负数的符号放到分子上。
                    }
                }
            }
        }
    }
    cout << Set.size() + 20 + 21;//因为没有计算横着和竖着的情况,别忘记加回去。
    return 0;
}

还可以用分式的方法储存,避免精度问题,记得约分!!!

相关