这里借用一下大佬的题解AcWing 2873. 平面切分 - AcWing
当只有一条线的时候那么这个平面就被分为2份
当有两条线的时候可分为两种情况:1.两条线平行2.两条线相交且有一个交点:
- 平行的话就可以分为3个部分
- 相交的话就分为4个部分
当有三条线的时候可分为三种情况:1,三条线相互平行2,三条线有1个交点3,三条线在两条线相交的情况下剩下一条线与其中一条线相交,与另一条线平行4,三条线在两条线相交的情况下剩下一条线分别与这两条线相交
1,4个交点
2,6个交点
3,6个交点
4,7个交点
那么综上所述:所有线共用一个交点和所有线有两个交点的情况一样,那么当每增加一条线,这条线每于前面的线有一个交点,那么就会增加一部分的平面,但最开始的两种情况是增加了2个部分,那么就在判断有几个交点的时候就先将答案加一个1,以便与后面的情况保持平衡,
因为给的方程是y = a * x + b; 所以可能给出的数据会有重边,那么就用<set>函数来去重边(内置的),但:
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
typedef pair<double , double> PII; //存储输入的坐标
set<PII> lines; //存储输入的边的
int res = 1; //一开始没边的时候就是一个大部分
int add_inscet(double a,double b) //增加的交点
{
set<PII> add_point; //存储的是当前边与其他边的交点
PII jiaodian; //前边与其他边的交点 的坐标
for(auto i = lines.begin();i!=lines.end();i++) //遍历当前所有的边
{
double x = i->first,y = i->second; //x是斜率,y是偏移量
//y = a * x + b; 输入的是a和b,那么a就是斜率b是偏移量,存储的也是a,b;
if(a!=x) //当前边的斜率不等于当前遍历的边的斜率,就证明至少有一个交点
{
jiaodian.first = (b - y)/(x - a); //求交点的横坐标
jiaodian.second = a * jiaodian.first + b; //求交点的纵坐标
add_point.insert(jiaodian); //把交点加入到交点集合中去
}
}
//a == x怎么办:
//a == x的话就是与其平行就没有交点,增加的部分就是单纯的随着增加的边而增加
return add_point.size(); //返回交点的数量
}
int main()
{
int n;
cin >> n; //边的数量
while(n--)
{
int a,b; //输入每一条边
cin >> a>> b;
int m = lines.size(); //把当前还没有加入边的集合的边的数量赋给m
//用来判断是不是有重边,如果有的话就输入下一组点,没有的话就计算交点
lines.insert({a,b}); //把输入的点加入边的集合
if (m != lines.size()) //判断有没有重边
{
res++; //先加一,因为没有交点到有一个或者两个交点是增加了两个部分(一个交点和两个交点增加的部分的情况一样)
res+=add_inscet(a,b); //计算答案
}
}
cout << res;
return 0;
}
本篇题解是为了自己能够加深印象方便以后理解的,如果又不好的地方就请及时告诉蒟蒻,如果能帮助到其他人就更好了