蓝桥杯 平面切分

蓝桥杯 平面切分

一、题目

在这里插入图片描述

二、题解

问题1: n条直线可以将一个平面划分成多少个部分平面?注意:这些直线有可能平行,也可能几条直线相较于一个交点!

解决步骤:

  • 不要想着一次性就将所有直线放到这些平面上,应该一条一条的把直线放到平面上。
  • 每次放入一条直线,看看这条直线会与平面上已有的直线产生多少个不同的交点。假如会产生a个交点,那么可以知道,放入了这条直线后,部分平面的个数会增加a+1
  • 从第1条直线开始放置到平面上,直至放置第n条结束。将每次放入一条直线后部分平面个数增加的个数累加起来就是最终的答案。

对上面的下划线处的内容的做如下解释:

第一幅图中是已经放置了5条直线,如果再放入第6条直线(绿色),可知这条绿色直线原来的直线的交点的个数为3个,那么,部分平面的个数就会增加3+1个

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q3ui43nP-1622984702331)(typoraPicture/c++常用函数快速入门/image-20210606204304229.png)]

问题2: n条直线最多可以将部分平面分为多少个部分?

​ 从问题1的讨论知道,如果每次放入一条直线都与原来的直线相交(即没有平行线),且产生的交点与原来直线的交点没有重合,那么此时放入了该直线之后,部分平面的个数增加就会最多!

放第1条放第2条放第3条放第4条放第n条
新直线与原直线的交点个数0123n-1
部分平面增加的个数0+1=11+1=22+1=33+1=4n-1+1=n

放入第一条直线之前,只有1个平面。那么,放入第1条、第2条、第3条…、第n条之后,总的平面个数为:1+1+2+3+4+…+n = 1+(n+1)*n/2

所以,n条直线最多可以将部分平面分为1+(n+1)*n/2个部分

程序

程序暂时没有进行优化,能通过全部测试用例。

#include <bits/stdc++.h>
#define LL long long
using namespace std;


int main()
{
    int N = 0;
    int plans = 0;
    cin >> N;
    set<pair<double, double> > setab; //使用set来存储a b值对,会自动剔除重复的a b值

    for(int i=0; i<N; i++){
        pair<double, double> temp;
        cin >> temp.first >> temp.second;
        setab.insert(temp);
    }

    set<pair<double, double> >::iterator iter1 = setab.begin();
    set<pair<double, double> > _setab; //不停的向其中添加直线

    for(; iter1!=setab.end(); iter1++){
        pair<double, double> temp = *iter1;

        if(_setab.size() <= 0){//当前_setab集合为空则直接插入到该集合中
            _setab.insert(temp);
            plans = 2;
            continue;
        }

        //将该直线与所有已有直线对比
        double a1=temp.first, b1=temp.second;
        double x, y;
        double a2, b2;
        set<pair<double, double> > setcp; //存储直线交点
        set<pair<double, double> >::iterator iter2 =_setab.begin();
        for(; iter2!=_setab.end(); iter2++){
            a2=iter2->first; b2=iter2->second;
            if(a1-a2 == 0){//平行则说明没有交点
                _setab.insert(temp);
                continue;
            }
            x=(b2-b1)/(a1-a2); y=(a1*b2-a2*b1)/(a1-a2);
            setcp.insert(pair<double, double>(x, y));
        }
        //则增加的平面数量 = 与已有直线交点的个数 + 1
        plans += (setcp.size()+1);
        _setab.insert(temp);
    }

    cout << plans << endl;
    return 0;
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值