当前位置:首页 > 洛谷 > 洛谷P2789题解:递归算法与避免重复计算的技巧

洛谷P2789题解:递归算法与避免重复计算的技巧

5个月前 (07-11)

洛谷P2789题解:递归算法与避免重复计算的技巧 洛谷题解 递归算法 组合数学 分治思想 C++ 第1张

一、题目解读

洛谷P2789题要求计算n条直线在平面上两两相交产生的交点总数。题目强调交点不重复,需考虑平行线情况。关键点在于如何高效枚举所有可能的交点组合,并排除重复结果。

二、解题思路

采用递归算法,核心思想是“分治+标记”。通过枚举每条线与其他线的平行关系,将问题分解为子问题:当前线与其他线平行或相交。为避免重复统计,使用全局数组A标记已存在的交点数,仅当新交点数未被记录时才累加。

三、解题步骤

1. 输入处理:获取总直线数n,初始化sum=0,A数组全0。

2. 递归函数plan(p,m):

○ 终止条件:p=0时,若m未出现,更新sum并标记A[m]。

○ 递归逻辑:枚举平行线数r(p到1),计算r条平行线与剩余p-r条线的交点数r*(p-r),递归调用plan(p-r, m+r*(p-r))。

3. 主函数:调用plan(n,0),输出sum。

四、代码与注释

#include <iostream>
#include <algorithm>

// 全局变量
int sum = 0;          // 总交点数之和
int p, n, r;          // p为剩余线数,n为总直线数,r为平行线数
bool A[100000] = {0}; // A[i]=1表示i个交点已存在,避免重复统计

// 递归函数:计算交点数
// p:剩余线数(当前待处理的线数)
// m:当前已计算的交点数
void plan(int p, int m) {
    // 终止条件:当剩余线数为0时,记录当前交点数
    if (p == 0) {
        if (A[m] == 0) { // 若该交点数未出现过,计入sum
            sum++;
        }
        A[m] = 1; // 标记为已存在
    } else {
        // 枚举平行线数量r(从p到1)
        for (int r = p; r >= 1; r--) {
            // 计算r条平行线与剩余p-r条线的交点数:r*(p-r)
            int newM = m + r * (p - r);
            // 递归处理剩余p-r条线
            plan(p - r, newM);
        }
    }
}

int main() {
    std::cin >> n; // 输入总直线数n
    plan(n, 0);    // 从n条线开始递归,初始交点数为0
    std::cout << sum << std::endl; // 输出总交点数之和
    return 0;
}

五、总结

本解法巧妙利用递归将复杂枚举转化为子问题求解,结合标记数组高效去重。核心在于理解平行线产生的交点数公式r*(p-r),并通过分治策略逐层递归。时间复杂度受递归深度影响,但通过避免重复计算显著优化结果。该思路对组合数学类问题具有参考价值。


原创内容 转载请注明出处

分享给朋友:

相关文章

牛客DP41精讲:当背包必须装满时,你的状态转移方程该如何调整?

牛客DP41精讲:当背包必须装满时,你的状态转移方程该如何调整?

题目重解我们面对一个经典背包问题的变体:给定n个物品,每个物品有重量w和价值v,背包容量为V。需要回答两个问题:1) 普通情况下能获得的最大价值;2) 必须恰好装满背包时的最大价值(若无法装满则输出0...

IOI 1994 洛谷1216:如何用动态规划高效解决数字三角形问题?附完整代码解析

IOI 1994 洛谷1216:如何用动态规划高效解决数字三角形问题?附完整代码解析

题目重解给定一个由数字组成的三角形结构,从顶部出发,每次可以移动到下方相邻的数字,最终到达底部。我们的目标是找到一条路径,使得路径上经过的数字总和最大。这个问题在实际中有许多应用场景,如最优路径规划、...

洛谷2181题解析:组合数学中顶点交点的计算与代码优化

洛谷2181题解析:组合数学中顶点交点的计算与代码优化

一、题目解读洛谷2181题要求计算n个顶点中任意选择4个顶点确定的交点数量。题目核心在于组合数学的应用,需通过排列组合公式推导结果,同时注意处理大数以避免溢出问题。理解题目中的“交点”定义(由4个顶点...

牛客NC67题解:汉诺塔递归算法与解题步骤

牛客NC67题解:汉诺塔递归算法与解题步骤

一、题目解读牛客NC67题要求解决汉诺塔问题,这是一个经典的递归算法题目。题目给定整数n,代表汉诺塔中的盘子数量,需要输出将n个盘子从起始柱移动到目标柱的所有步骤。汉诺塔问题规则为:每次只能移动一个盘...

洛谷1656题解:基于Tarjan算法求解割边问题(附代码与详细步骤)

洛谷1656题解:基于Tarjan算法求解割边问题(附代码与详细步骤)

一、题目解读洛谷1656题要求在无向图中找出所有割边(即删除后导致图不连通的边)。题目核心在于判断图的连通性,并识别哪些边是“桥”。需理解图论中的连通分量概念,以及如何通过算法高效定位割边。二、解题思...

洛谷P2190题解:铁路售票系统车厢计算(差分数组+前缀和优化)

洛谷P2190题解:铁路售票系统车厢计算(差分数组+前缀和优化)

一、题目解读洛谷P2190题要求解决铁路售票系统中的车厢数量计算问题。题目给定n个车站和m条订票申请,每条申请包含区间[x,y)及乘客数z。需要计算在不超载的情况下(每节车厢最多36人),满足所有乘客...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。