P2789 直线交点数
我们将条直线编号,分别称为直线、直线、…、直线。直线 与直线 最多有一个交点,直线与直线和直线最多有个交点,……,直线与其它 条直线最多 个交点。
由此看出,条无三线共点的直线最多的交点数 。
但本题我们要求解的是:这 条直线共有多少种不同的交点数? 仍然从举例出发。下面列举了 四种情况各自的交点情况:
具体分析一下 的情况:
已确定的交点数量:,待确定的直线条数:,可能造成的交点数:分情况讨论(对照上面的图):
-
条直线平行,则个交点。
-
条直线平行,则个交点。
-
条直线平行,则这条直线与另条直线的交点数为, 而另外条直线之间可能有个或个交点 (见 的情况),共 个交点或 个交点。其实这里面的就是前面的调用者把自己知道的已知交点数量做为小纸条传递给下一个分身,让它继续探索到结束。
-
条直线均不平行(可看成 条直线平行),这 条直线与其它 条直线的交点数为 ,而其它 条直线之间的交点数为,共个交点。
经过以上分析,我们可以得如下结论:
条直线的交点方案=条平行线与条直线交叉的交点数+(p-r)条直线本身的交点方案
=+条直线本身的交点方案
#include <bits/stdc++.h>
using namespace std;
//https://www.luogu.com.cn/blog/user34320/solution-p2789
using namespace std;
const int N = 310;
bool visit[N];
/**
对p条直线分情况讨论平行线的条数,已知在有r条平行线时有(p-r)条线与他们相交于p*(p-r)个交点,
再加上对于这p-r个交点的相交组合即可!!!
*/
/**
* 功能:讨论处理n条线的交点数情况有哪些
* @param p n条线
* @param sum 已经确定的交点数量
*/
void g(int p, int sum) {
//标记k个结点数量是存在的
visit[sum] = true;
//递归出口,如果0条直线,就返回吧
if (p == 0) return;
//n条直线中,存在的平行线条数,需要逐个遍历一遍
for (int r = p; r >= 1; r--)
g(p - r, r * (p - r) + sum);
}
int main() {
//输入
int n, ans;
cin >> n;
//从n条直线,交点数量为0(全部平行)开始讨论
g(n, 0);
//统计结果
for (int i = 0; i < N; i++) ans += visit[i];
//输出结果
cout << ans;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!