HDU 1466 计算直线的交点数

7 篇文章 0 订阅

这题对我来说好处挺多, 收获不少。

首先声明下这题是看的HDU PPT上的讲解。

第一次写的时候PPT不懂, 只好自己写, 写了半天发现某一些交点方案被我的dp方程给覆盖了

输入:4 输出: 0 3 4 6 

少了个5, 自己调试, 无论我怎么改都不能输出所有方案。

只好再看一遍PPT, 看完后发现怎么去改了。

一直写, 迷迷糊糊的一致没能写好。

今天认真的写了写, 弄出来了。 

但是我调试发现有很多重复方案, 这些都是需要剔除的。

我想在输出的时候给剔除, 之后也还是不对。

在调试, 输出每条直线的案例数量。

发现最多的达到了160 000 这可吓坏我了。

开这么大数组, 很不现实。

上网搜吧, 正好搜到个unique。就用上了。

然后,  然后就A了。。。

unique详解 C++ STL http://stl123.net/algorithm/unique/

文章参考地方:http://blog.csdn.net/zxy_snow/article/details/6685509

#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <string>
using namespace std;
int len[500], dp[25][500], n;
int cmp(const void *_a, const void *_b)
{
	return *(int *)_a - *(int *)_b;
}
void init()
{
	int i, j, k, cnt;
	len[0] = 0; len[1] = 1;
	memset(dp, 0, sizeof(dp));
	//直线条数
	for (i = 1; i <= 20; i++)
	{
		cnt = 0;
		//平行边数
		for (j = 1; j <= i; j++)
			//i-j条直线的交点方案
			for (k = 0; k <= len[i-j]; k++)
			{
				//i条平行线与i-j条直线交叉的交点数 + 
				//i-j条直线本身的交点方案
				dp[i][cnt++] = j * (i - j) + dp[i - j][k];
				//printf("i = %d cnt - 1 = %d dp[i][cnt-1] = %d\n", i, cnt-1, dp[i][cnt-1]);
			}
		//i条直线的焦点方案数量(有重复元素)
		len[i] = cnt;
		//printf("i = %d len[i] = %d\n", i, len[i]);
		qsort(dp[i], cnt, sizeof(int), cmp);
		//unique	头文件 <algorithm>
		//用途		剔除某一区间中重复元素
		//返回值	返回剔除元素后的新区间的最后一个元素的迭代器位置
		//因此返回值减去dp[i]为该区间长度
		len[i] = unique(dp[i], dp[i] + cnt) - dp[i];
	}
}
int main()
{
	int i, previous;
	init();
	while (scanf("%d", &n) != EOF)
	{
		if (n > 0)
		{
			printf("0");	previous = 0;
			for (i = 1; i < len[n]; i++)
			{
				if (dp[n][i] != previous)
					printf(" %d", dp[n][i]);
				previous = dp[n][i];
			}
			printf("\n");
		}
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值