暑假编程训练---G:计算直线的交点数
来源:互联网 发布:淘宝个性签名大全 编辑:程序博客网 时间:2024/04/29 22:59
问题描述
平面上有n条直线,且无三线共点,问这些直线能有多少种不同交点数。
比如,如果n=2,则可能的交点数量为0(平行)或者1(不平行)。
Input
输入数据包含多个测试实例,每个测试实例占一行,每行包含一个正整数n(n<=20),n表示直线的数量.
Output
每个测试实例对应一行输出,从小到大列出所有相交方案,其中每个数为可能的交点数,每行的整数之间用一个空格隔开。
Sample Input
2
4
Sample Output
0 1
0 3 4 5 6 (表示在4条直线的情况下,可能有0,3,4,5,6个交点)
问题分析
由上图可以知道:
n = 1时 有0个交点
n = 2时 有0, 1个交点
n = 3时 有0, 2, 3个交点
n = 4时 有0, 3, 4, 5, 6个交点
从n = 4的情况出发,可以看到是在减少平行线的数量。假设有n条直线,那么这n条直线的交点数可以看作是(n-i)*i与j的和,这里(n-i)表示平行线的条数,i表示自由线的条数,j表示i条自由线的交点数。因为1条自由线与(n-i)条平行线必定有(n-i)*1个交点,这里申明下自由线与平行线不会平行,否则自由线与平行线就没有区分的必要了。那么i条自由线与平行线的交点总数就为(n-i)*i,由于i条自由线可能互相平行也可能相交,故需要加上i条自由线自身的交点数j。其实这个j与计算n条直线的交点数的方法是一样的,只不过规模缩小了。
这道题在最初分析后觉得可以用动态规划的方法来做,但细看之后,这题不涉及最优子结构的问题,所以只是单纯的递归思想而已。
M条直线的交点方案数=(m-r)条平行线与r条直线交叉的交点数+r条直线本身的交点方案=
(m-r)*r +r条直线之间的交点数。
#include<stdio.h>
int main ()
{
//不浪费内存原则下,由于m的值最大为20,i的值最大为19,j的值最大为190
//再加上数组只存储0或者1,故用unsigned char类型足矣
int m, i, j, x[21][191] = {0};
//0个交点的情况是无论几条线都有的方案
for (i = 1; i <= 20; i++)
x[i][0] = 1;
for (m = 2; m <= 20; m++) //总共有20条直线
for (i = 1; i < m; i++) //i为自由直线条数,最多m-1条
for (j = 0; j <= 190; j++) //j表示交点数,最多190个
if (x[i][j] == 1) //如果i条线j个交点为真
x[m][(m - i) * i + j] = 1;
//那么m - i条平行线 * i条自由线
//的交点 + j个交点也为真
while (scanf ("%d", &m) != EOF)
{
printf ("0");
j = (m * (m - 1) / 2);
for (i = 1; i <= j; i++)
if (x[m][i])
printf (" %d", i);
printf ("\n");
}
return 0;
平面上有n条直线,且无三线共点,问这些直线能有多少种不同交点数。
比如,如果n=2,则可能的交点数量为0(平行)或者1(不平行)。
Input
输入数据包含多个测试实例,每个测试实例占一行,每行包含一个正整数n(n<=20),n表示直线的数量.
Output
每个测试实例对应一行输出,从小到大列出所有相交方案,其中每个数为可能的交点数,每行的整数之间用一个空格隔开。
Sample Input
2
4
Sample Output
0 1
0 3 4 5 6 (表示在4条直线的情况下,可能有0,3,4,5,6个交点)
问题分析
由上图可以知道:
n = 1时 有0个交点
n = 2时 有0, 1个交点
n = 3时 有0, 2, 3个交点
n = 4时 有0, 3, 4, 5, 6个交点
从n = 4的情况出发,可以看到是在减少平行线的数量。假设有n条直线,那么这n条直线的交点数可以看作是(n-i)*i与j的和,这里(n-i)表示平行线的条数,i表示自由线的条数,j表示i条自由线的交点数。因为1条自由线与(n-i)条平行线必定有(n-i)*1个交点,这里申明下自由线与平行线不会平行,否则自由线与平行线就没有区分的必要了。那么i条自由线与平行线的交点总数就为(n-i)*i,由于i条自由线可能互相平行也可能相交,故需要加上i条自由线自身的交点数j。其实这个j与计算n条直线的交点数的方法是一样的,只不过规模缩小了。
这道题在最初分析后觉得可以用动态规划的方法来做,但细看之后,这题不涉及最优子结构的问题,所以只是单纯的递归思想而已。
M条直线的交点方案数=(m-r)条平行线与r条直线交叉的交点数+r条直线本身的交点方案=
(m-r)*r +r条直线之间的交点数。
#include<stdio.h>
int main ()
{
//不浪费内存原则下,由于m的值最大为20,i的值最大为19,j的值最大为190
//再加上数组只存储0或者1,故用unsigned char类型足矣
int m, i, j, x[21][191] = {0};
//0个交点的情况是无论几条线都有的方案
for (i = 1; i <= 20; i++)
x[i][0] = 1;
for (m = 2; m <= 20; m++) //总共有20条直线
for (i = 1; i < m; i++) //i为自由直线条数,最多m-1条
for (j = 0; j <= 190; j++) //j表示交点数,最多190个
if (x[i][j] == 1) //如果i条线j个交点为真
x[m][(m - i) * i + j] = 1;
//那么m - i条平行线 * i条自由线
//的交点 + j个交点也为真
while (scanf ("%d", &m) != EOF)
{
printf ("0");
j = (m * (m - 1) / 2);
for (i = 1; i <= j; i++)
if (x[m][i])
printf (" %d", i);
printf ("\n");
}
return 0;
}
- 暑假编程训练---G:计算直线的交点数
- G题 hdu 1466 计算直线的交点数
- 计算直线的交点数
- 计算直线的交点数
- 计算直线的交点数
- 计算直线的交点数
- 计算直线的交点数
- 计算直线的交点数
- 计算直线的交点数
- 计算直线的交点数
- 1466 计算直线的交点数
- HDU 1466 计算直线的交点数
- hdu 1466 计算直线的交点数
- hdu1466计算直线的交点数
- HDOJ 1466 计算直线的交点数
- hdu 1466 计算直线的交点数
- hdu 1466 计算直线的交点数
- 计算直线的交点数(HDU 1466)
- Free Cash
- 【两种实用方法 确保Win7文件系统稳定性】
- 应用程序之测试工具
- Populating Next Right Pointers in Each Node (I & II)
- 山特UPS电源蓄电池容量和数量的计算方法
- 暑假编程训练---G:计算直线的交点数
- android蓝牙连接createRfcommSocketToServiceRecord方法抛出异常问题
- .NET WinForm下StatusStrip控件如何设置分隔线及部分子控件右对齐
- 【OpenStack】OpenStack Metering Using Ceilometer
- 一个用poi导出excel的例子
- KVO/KVC的理解
- 爬虫豆瓣 -- v1.0
- make[3]: *** [out/target/common/docs/doc-comment-check-timestamp] Error 45
- xliff XML本地化数据交换格式