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

 

posted @ 2020-10-24 10:21  Fool_one  阅读(561)  评论(0编辑  收藏  举报