蓝桥杯 直线
#includeusing namespace std; set double, double>> s; vector int, 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 pair int, int>, pair<int, int>> PP; set int, 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; }
还可以用分式的方法储存,避免精度问题,记得约分!!!