HDU1466 计算直线的交点数

1、n条直线互不平行且无三线共点的最多交点数max=1+2+……(n-1)=n(n-1)/2
2、一般统计的方法:
假设一共有n=a+b条直线 即n条直线分成2组,分别为a条和b条),则
     总的交点数= a内的交点数 +b内的交点数 +a,b之间的交点数
3、我们来分析加入第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个不同交点数。
我们发现:
m条直线的交点方案数=(m-r)条平行线与r条直线交叉的交点数  + r条直线本身的交点方案
                                           =(m-r)*r+r条之间本身的交点方案数(0<=r<m)
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <math.h>
#define MAX_N 20
#define MAX_INTERSECTS ((MAX_N+1)*MAX_N>>1)
int intersects[MAX_N+1][MAX_INTERSECTS];//交点数组
int nums[MAX_N+1];//对应直线条数的肯能的交点数
bool isExist[MAX_INTERSECTS+1];
int main(){
	int i,r,j;
	int n;
	//初始化
	intersects[1][0]=0;
	nums[1] = 1;
	for(i=2;i<=MAX_N;++i){
		memset(isExist,false,sizeof(isExist));
		isExist[0] = true;//都平行
		for(r=1;r<i;++r){
			for(j=0;j<nums[r];++j){
				int t = (i-r)*r + intersects[r][j];
				isExist[t] = true;
			}
		}
		int count = 0;
		for(j=0;j<MAX_INTERSECTS;++j){
			if(isExist[j])
				intersects[i][count++]=j;
		}
		nums[i] = count;
	}
	while(scanf("%d",&n)!=EOF){
		for(i=0;i<nums[n];++i){
			if(i==0){
				printf("%d",intersects[n][i]);
			}else
				printf(" %d",intersects[n][i]);			
		}
		printf("\n");
	}
	return 0;
}

发布了27 篇原创文章 · 获赞 4 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/hysfwjr/article/details/9058835