HDU 1466 计算直线的交点数

6 篇文章 0 订阅

这其实是一道递推题,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[n][x-1]!=0&&dp[n][x]==0))
			{
				printf(" %d",dp[n][x]);
				x++;
			}
		puts("");
	}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值