计算直线的交点数
我们知道:
n条直线互不平行且无三线共点的最多交点数max=1+2+……(n-1)=n(n-1)/2,
但本题不这么简单,因为问题问的是:这些直线有多少种不同的交点数?
先来看个统计的方法:
假设一共有n=a+b条直线(即n条直线分成2组,分别为a条和b条)
则总的交点数= a内的交点数+b内的交点数+a,b之间的交点数
我们来分析加入第N条直线的情况(这里以N=4为例):
(分类方法:和第N条直线平行的在a组,其余在b组)
1、第四条与其余直线全部平行 => 0+4*0+0=0;
2、第四条与其中两条平行,交点数为0+(n-1)*1+0=3;
3、第四条与其中一条平行,这两条平行直线和另外两点直线的交点数为(n-2)*2=4,而另外两条直线既可能平行也可能相交,因此可能交点数为:
0+(n-2)*2+0=4 或者 0+(n-2)*2+1=5
4, 第四条直线不与任何一条直线平行,交点数为:
0+(n-3)*3+0=3 或0+ (n-3)*3+2=5 或0+ (n-3)*3+3=6
即n=4时,有0个,3个,4个,5个,6个不同交点数。
从上述n=4的分析过程中,我们发现:m条直线的交点方案数=(m-r)条平行线与r条直线交叉的交点数 + r条直线本身的交点方案
=(m-r)*r+r条之间本身的交点方案数(0<=r<m)
#include <stdio.h> #include <string.h> int main() { int a[21][200],i,j,k,n; memset(a,0,sizeof(a)); a[0][0]=1; a[1][0]=1; a[2][0]=1; a[2][1]=1; for(i=3;i<=20;i++) for(k=i-1;k>=0;k--) for(j=0;j<=k*(k-1)/2;j++) if(a[k][j]==1) a[i][(i-k)*k+j]=1; while(scanf("%d",&n)!=EOF) { for(i=0;i<=n*(n-1)/2;i++) { if(i==0) { printf("0"); continue; } if(a[n][i]==1) printf(" %d",i); } printf("\n"); } return 0; }