/*
* Copyright (c) 2014, 烟台大学计算机学院
* All rights reserved.
* 文件名称:test.cpp
* 作 者:李晓凯
* 完成日期:2015年 6 月 3 日
* 版 本 号:v1.0
*
* 问题描述:
* 输入描述:
* 程序输出:
*/
Problem Description
平面上有n条直线,且无三线共点,问这些直线能有多少种不同交点数。
比如,如果n=2,则可能的交点数量为0(平行)或者1(不平行)。
比如,如果n=2,则可能的交点数量为0(平行)或者1(不平行)。
Input
输入数据包含多个测试实例,每个测试实例占一行,每行包含一个正整数n(n<=20),n表示直线的数量.
Output
每个测试实例对应一行输出,从小到大列出所有相交方案,其中每个数为可能的交点数,每行的整数之间用一个空格隔开。
Sample Input
2 3
Sample Output
0 1 0 2 3
解析:
容易列举出N=1,2,3的情况:
0
0,1
0,2,3
如果已知<N的情况,我们来分析加入第N条直线的情况(这里N=4):
1、第四条与其余直线全部平行 => 无交点;
2、第四条与其中两条平行,交点数为(n-1)*1+0=3;
3、第四条与其中一条平行,这两条平行直线和另外两点直线的交点数为(n-2)*2=4,而另外两条直线既可能平行也可能相交,因此可能交点数为:
(n-2)*2+0=4 或者 (n-2)*2+1=5
4、第四条直线不与任何一条直线平行,交点数为:
(n-3)*3+0=3 或者 (n-3)*3+2=5 或者 (n-3)*3+3=6即n=4时,有0个,3个,4个,5个,6个不同交点数。
从上述n=4的分析过程中,我们发现:
m条直线的交点方案数
=(m-r)条平行线与r条直线交叉的交点数
+ r条直线本身的交点方案
=(m-r)*r+r条之间本身的交点方案数(1<=r<=m)
代码:
超限代码:
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
int a[21][200],i,n;
memset(a,0,sizeof(a));
for(i=0; i<21; ++i)
a[i][0]=0; //所有直线都平行,即0个交点
for(n=2; n<21; ++n)
for(i=1; i<n; ++i)
for(int j=0; j<200; ++j)
{
a[n-i][j]=1;
a[n][j+i*(n-i)]=1;
}
while(cin>>n)
{
for(i=0; i<=n*(n-1)/2; ++i)
{
if(a[n][i])
cout <<i<<" ";
}
cout<<endl;
}
return 0;
}
不知道为什么,这个代码就是超限,求大神解释!!!
AC代码:
#include<iostream>
using namespace std;
int main()
{
int i,n,s[21][200],j,k;
for(i=1; i<=20; i++)
for(j=0; j<=200; j++)
s[i][j]=0;
s[0][0]=1;
s[1][0]=1;
s[2][0]=1;
s[2][1]=1;
for(i=3; i<=20; i++)
for(j=0; j<i; j++)
for(k=0; k<=(j-1)*j/2; k++)
if(s[j][k]==1)
s[i][k+j*(i-j)]=1;
while(cin>>n)
{
cout<<"0";
for(i=1; i<=(n-1)*n/2; i++)
if(s[n][i]==1)
cout<<" "<<i;
cout<<endl;
}
return 0;
}