洛谷p2789 直线交点数 求方案总数

在这里插入图片描述

题目分析

题目难度:普及+/提高
小学二年级知识: n条直线相交(没有三点共线),能够得到的最大交点数目为n(n-1)/2
然后本题要求的是n条直线相交(没有三点共线),能够得到多少种不同交点数目的方案?
手动模拟n=4时的情况, 以有多少条平行线为分类讨论的依据

设平行线的数目为k,则k的范围为[1,4];设交点数目为node
	交点数目node=平行线与在外面直线形成的交点数目+外面直线自由排列形成的交点数目(有多种可能)
当k=4时,4条直线平行,没有交点,node=0;
当k=3时,3条直线平行,1条直线在外面,node=1*(4-1)=1*3=3
当k=2时,2条直线平行,2条直线在外面,而在外面的两条直线又有两种情况(这两条直线平行,或者相交),所以
         node=2*2+0=4或者2*2+1=5
当k=1时,1条直线平行,3条直线外面,而在外面的三条直线将演变成n=3时的分类讨论情况!

下为n=3时的讨论情况(上述为n=4)
当k=3时,node=0
当k=2时,node=2*(3-2)+0=2
当k=1时,1条直线平行,两条直线在外面,演变成n=2的情况,即node=1*(3-1)+0=2或者node=1*(3-1)+1=3
故当n=3时,node=0,2,3有三种方案

再回到n=4时,
现在k=1,1条直线平行,3条直线在外面,而在外面的三条直线的所有交点数目我们已经求出来了(注意这里不能
直接用n=3时的方案数相加,因为会和前面k的其他情况重合,所以必须计算交点数目)
node=1*3+0或者1*3+2或者1*3+3 =3,5,6
综上所述,n=4时,交点数目可能为0,3,4,5,6  即方案总数为5

很显然,递归的思路就出来了。
然后最后再设定好参数变量,out_line表示在外面的直线数量,初始化为n;sum表示当前形成的交点数目,初始化为0;递归终止条件为out_line=0时,即外面没有直线了!

AC代码
//Author:snnu_lgw
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ans;
int num[1000]; //数组记录出现的不同的交点数

// out_line条直线在外时 sum为此时形成的交点数目(已经确定的交点数目,即与平行线形成的交点)
void  spss(int out_line,int sum)
{
	if(out_line==0) 
		{ //如果在外面的直线为0,即递归可以结束了 其余的直线都已经处理好了 
			if(num[sum]==0)
				ans++;
			num[sum] = 1;
			return;
		}
	for(int i=1;i<=out_line;i++)
		{ //i表示把外面的直线拉到平行里去 
			int surplus = i*(out_line-i);//平行交出来的交点数
			int next_out_line = out_line-i; //外面的直线数目要进行更新! 
			spss(next_out_line,sum+surplus); 
		}
} 
int main()
{
	int n;
	cin>>n;
	spss(n,0);//一开始n条直线在外面,然后有n条直线平行,n-1条,n-2条,……1条平行 
	cout<<ans; 
	return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值