前言
建议本题评黄,因为需要较强的数学能力。
如果格式炸了去这里看哦
题意
给出 \(N\) 条直线的解析式 \(y=kx+b\),求出这些直线把平面分成了几部分。
思路
看到这道题我们会梦回小学五年级在某场考试或某张毒瘤数学试卷里做到的题目:
\[\boxed{\begin{gathered} \color{#FFFFFF}\rule{400pt}{110pt}\cr[-100pt] \begin{gathered}\Large\textbf{** 小学五年级数学拓展试卷}\end{gathered} \cr \underline{\text{114.}}\text{完成以下一道应用题}\kern{250pt}\cr \begin{gathered} \end{gathered} \textcolor{#FFFFFF}{\underline{\kern{280pt}}}\cr \text{\kern{20pt}已知 1 条直线可以把平面最多分成两部分,2 条直线可以把平面最}\cr \text{~多分成 4 部分,3 条最多可以分成 7 部分,请问 4、5 条直线最多可}\cr \text{以把平面分成几部分?\kern{190pt}}\cr \end{gathered}} \]回忆一下我们当时是如何做出这样的题目的?找规律?画图?蒙答案?
或者我们可以重复这样的步骤。
- 当没有任何直线时,显然平面只有一部分。
- 当有 \(1\) 条直线时,平面有 \(2\) 个部分。
- 当有 \(2\) 条直线时,第 \(2\) 条直线交第 \(1\) 条于一个点,所以增加了 \(2\) 个部分,共 \(4\) 个部分。
- 当有 \(3\) 条直线时,第 \(3\) 条直线交前两条各于一个点,所以又增加了 \(3\) 个部分,共 \(7\) 个部分 (假设没有三线共点或平行)。
- 当有 \(4\) 条时,增加 \(3\) 个交点,\(4\) 个部分,共 \(11\) 个部分。
- 当有 \(5\) 条时,增加 \(4\) 个交点,\(5\) 个部分,共 \(16\) 个部分。
以上推断均保证没有三线共点或平行的情况。
仔细阅读加粗部分显然可以发现,每增加 \(n\) 个交点,会多出 \(n+1\) 个部分。
我们就成功的把求几部分的问题转化成了求交点的问题。
接着考虑 三点共线 和 平行 的情况。
对于三点共线,若一条直线于另两条直线的交点交在一起 (注意我的表述方式),因为这一点之前已经分出了它所对应的部分,所以不需要再次统计。
对于一对直线平行,则仅对这两条直线来说,它们没有任何交点,因此这对直线不需要计算交点。
综上所述,我们只要模拟以上过程,不断添加一条一条直线并且计算交点个数即可。
代码
#include <iostream>
#include <set>
#include <vector>
#define i64 long long
#define reg register
#define qwq puts("fzy qwq ~");
#define pb push_back
#define Line pair<double, double>
#define kk first
#define bb second
using namespace std;
int n, tmp, ans = 1;
double xk, xb, k1, k2, b1, b2;
set<Line> l;
vector<int> k, b;
void init()
{
for (reg int i = 1; i <= n; ++i)
{
scanf("%lf%lf", &xk, &xb);
l.insert(make_pair(xk, xb)); // 使用 set 去重并顺手排序
}
for (reg auto x : l)
k.pb(x.kk), b.pb(x.bb); // 将直线放回 vector O(1) 访问降低常数
}
int main()
{
scanf("%d", &n);
init();
Line p;
for (reg int i = 0; i < (int)k.size(); ++i) //枚举每一条直线
{
set<Line> pos; // 交点的集合
for (reg int j = i - 1; j >= 0; --j)
{
k1 = k[i], b1 = b[i],
k2 = k[j], b2 = b[j];
if (k1 == k2) continue; // 平行,直接计算下一条直线
p.kk = (b2 - b1) / (k1 - k2); // 求得交点
p.bb = k1 * ((b2 - b1) / (k1 - k2)) + b1; //
pos.insert(p);
}
ans += pos.size() + 1; // 添加新分出的部分
}
printf("%d\n", ans);
return 0;
}
标签:直线,P8720,题解,gathered,蓝桥,交点,cr,部分,define
From: https://www.cnblogs.com/YttriumWillow/p/17154550.html