hdu 1466 计算直线的交点数(递推+数学)

计算直线的交点数

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 9801    Accepted Submission(s): 4469


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

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

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

Sample Input
 
  
2 3
 

Sample Output
 
  
0 1 0 2 3
 

Author
lcy
 

先考虑n=20时,最多有多少个交点,每条直线上最多有n-1个点,有n条直线,每个点都被计算了两次,所以最多有n(n-1)/2个交点。

我们可以从n-1条直线相交的情况推导出n条直线的相交情况,考虑到直线的关系不是相交就是平行,我们可以推倒一下n=4的情况:

  已知n=3时有0,2,3;

  (1):第四条直线与前三条平行,则有0;

  (2):第四条直线与其中两条平行,则有3;

  (3):第四条直线与其中一条平行,则有4,5;

  (4):第四条直线不与任何直线平行,则有3,5,6;

  大致可以知道当有j条边与第n条直线不平行是时候有(n-j)*j加上j条直线的交点,

  得出状态dp[j][j条边的交点]存在,得出状态dp[n][(n-j)*j+j条直线的交点]存在,

#include<cstdio>
#include <algorithm>  
#include <cstring> 
#define LL long long
using namespace std;
int a[25][210];
int main()
{
	int n;
	for(int i=0;i<=20;i++)
	   a[i][0]=1;
	for(int i=2;i<=20;i++)
	{
		for(int j=1;j<i;j++)
		{
			for(int k=0;k<200;k++)
			{
				if(a[j][k])   //判断不平行的直线个数j有k个交点的情况是否存在
				{
					a[i][(i-j)*j+k]=1;
				}
			}
		}
	}
	while(scanf("%d",&n)!=EOF)
	{
		printf("0");
		for(int i=1;i<200;i++)
		{
			if(a[n][i])
			{
				printf(" %d",i);
			}
		}
		printf("\n");
	}
	return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_35634181/article/details/62058245