您的位置:首页 > 其它

HDU 1466 计算直线的交点数

2014-10-25 20:42 211 查看
这其实是一道递推题,dp的思想其实还不明确。。

Problem Description

平面上有n条直线,且无三线共点,问这些直线能有多少种不同交点数。

比如,如果n=2,则可能的交点数量为0(平行)或者1(不平行)。

Input

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

Output

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

Sample Input

2

3

Sample Output

0 1

0 2 3

分析4条直线时的情况,发现可以分成三种情况:

1.有三条直线平行线,一条自由线

2.有两条直线平行线,两条自由线

3.有一条直线平行线,三条自由线

三种情况中,有些地方是有重复的,需要去重复,不然会增加空间复杂度。

#include<iostream>
#include<stdlib.h>
using namespace std;
#define size 200//查看结果后继续优化。。

int dp[22][size];
int len[22];

void dpcreate()
{
memset(dp,0,sizeof(dp));
dp[0][0]=0,len[0]=1;
dp[1][1]=0,len[1]=1;
dp[2][1]=0,dp[2][2]=1,len[2]=2;
dp[3][1]=0,dp[3][2]=2,dp[3][3]=3,len[3]=3;
for(int i=4;i<22;i++)//给定dp[i][x]
{
dp[i][1]=0;//第一种情况必定为0
int x=2;//初始化x
for(int r=i-1;r>0;r--)//遍历r=i-1到1。
{

for(int j=1;j<=len[r];j++)
{
dp[i][x]=dp[r][j]+r*(i-r);
x++;
for(int k=x-2;k>0;k--)//消去相同的,减少空间复杂度
{
if(dp[i][x-1]==dp[i][k])
{
x--;//消掉
break;
}
}

}
}
dp[i][x]=0;//消去尾巴
len[i]=x-1;//确定情况长度
}
}

int cmp ( const void *a , const void *b )
{
return *(int *)a - *(int *)b;
}

int main()
{
dpcreate();
for(int i=4;i<21;i++)
{
qsort(dp[i],len[i]+1,cmp);
}
int n;
while(scanf("%d",&n)!=EOF)
{
if(n==1||n==0)
{
printf("0\n");
continue;
}
int x=2;
printf("0");
while(!(dp
[x-1]!=0&&dp
[x]==0))
{
printf(" %d",dp
[x]);
x++;
}
puts("");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: