问题1174:计算直线的交点

问题重述:

平面上有n条直线,且无三线共点,问这些直线能有多少种不同交点数。 比如,如果n=2,则可能的交点数量为0(平行)或者1(不平行)。

输入:

输入数据包含多个测试实例,每个测试实例占一行,每行包含一个正整数n(n<=20),n表示直线的数量.

输出:

每个测试实例对应一行输出,从小到大列出所有相交方案,其中每个数为可能的交点数,每行的整数之间用一个空格隔开。

样例输入:

2

3

样例输出:

0 1

0 2 3

 

题解:

n条直线,交点最大为n*(n-1)/2。

当n=1, 2, 3时,交点个数易知为(0), (0, 1), (0, 2, 3),当n=4时,分一下四种情况:

        1. 四条线都平行,交点为 0;

        2. 三条线平行,交点个数为 3*(n-3)[第4条线与前三条线交点数] + 0[第4条线自身交点数U1];

        3. 两条线平行,交点个数为 2*(n-2)[第3, 4条线与前两条线交点数] + 0 or 1[第3, 4条线之间的交点数U2];

        4. 一条线平行(都不平行),交点个数为1*(n-1) + 0 or 2 or 3[第2, 3, 4条线之间交点数U3];

由此可知n条线的交点数为 Un = { i*(n-i) + Un-i }, for 0 <= i < n; 其中集合的加法是 元素分别加集合中的每一元素。得出伪代码:

U0 = {0}, U1 = {0}

for n=2 to N:

    Un = {};

    for i = 1 to n:

        Un = Un U {i*(n-i)+Un-i};

代码实现如下:

利用c[i][j]=1表示i条线包含j个交点这一项,从而实现并运算。

#include <iostream>
using namespace std;

int main(){
	int c[21][200] = {0}; //20条线最后有200个交点
	for(int i = 0; i < 21; i++) //任意i条直线必有0个交点这一项(全部平行)
		c[i][0] = 1;
	for(int n = 2; n < 21; n++){ //集合大小n从2到20
		for(int i = 1; i < n; i++){ //对于任意i条平行直线(1<=i<n)
			for(int j = 0; j < 200; j++){ //判断200个交点项的每一项
				if(c[n-i][j])	c[n][i * (n - i) + j] = 1; //Un = { Un U Un-i + i*(n-i) }
			}
		}
	}
	int n, max;
	while(cin >> n){
		max = n*(n-1)/2;
		for(int i = 0; i <= max; i++)
			if(c[n][i])	cout << i << " ";
		cout << endl;
	}
	return 0;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值