这题对我来说好处挺多, 收获不少。
首先声明下这题是看的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;
}