[2020蓝桥杯B组省赛] I-平面切分
题解
考几何,唉,这题死的不冤。
这一题的核心思想是递推,你需要判平行和重点,每加入一条边,和其余已经存在的边进行比较,如果平行则无需继续向下做,否则,求交点,判重点,因为存在多条边相交于同一个点,这就需要去重了,最后需要加 1,因为最后会形成一个闭合的区间,新生成的,之后累加,即每加入一条边所划分的区域都需加入统计中。
#include <iostream> #include <vector> #include <cmath> using namespace std; const int MAXN = 1010, INF = 1e9; int n, ans; int a[MAXN], b[MAXN]; struct Point { double x, y; }; bool isequal(Point e1, Point e2) { //注意浮点数的比较 return (abs(e1.x - e2.x) <= 1e-2 && abs(e1.y - e2.y) <= 1e-2); } Point crosspoint(int m, int n) { double x1 = a[m], x2 = a[n], y1 = b[m], y2 = b[n]; //平行则无交点 if (x1 == x2) { return Point {INF, INF}; } Point cp = Point{}; cp.x = (y2 - y1) / (x1 - x2); cp.y = (x1 * y2 - x2 * y1) / (x1 - x2); return cp; } int main() { cin >> n; for (int i = 1; i <= n; ++i) { cin >> a[i] >> b[i]; } // 初始 n = 1,划分成两个区域 ans = 2; for (int i = 2; i <= n; ++i) { vector <Point> v; bool flag = false; for (int j = 1; j < i; ++j) { // i 为新加入的点,与之前的点做划分 //判断直线 i, j是否存在交点 Point now = crosspoint(i, j); //直线 i, j不存在交点 if (now.x == INF || now.y == INF) { continue; } //直线i, j存在交点 for (int k = 0; k < v.size(); ++k) { //判重点 if (isequal(now, v[k])) { flag = true; } } if (!flag) { v.push_back(now); } } ans += v.size() + 1; } cout << ans << endl; return 0; }