时间限制: 1Sec 内存限制: 128MB
题目描述
平面上有n条直线,且无三线共点,问这些直线能有多少种不同交点数。
比如,如果n=2,则可能的交点数量为0(平行)或者1(不平行)。
输入
输入数据包含多个测试实例,每个测试实例占一行,每行包含一个正整数n(n<=20),n表示直线的数量.
输出
每个测试实例对应一行输出,从小到大列出所有相交方案,其中每个数为可能的交点数,每行的整数之间用一个空格隔开。
样例输入
2
3
样例输出
0 1
0 2 3
Code&Analysis
n 交点数
1 0
2 0 1
3 0 2 3
4 0 3 4 5 6
5 0 4 6 7 8 9 10
6 0 5 8 9 11 12
...
n 0 n-1...
----------------------------------------------------------
n条直线,i个平行直线
n=5
i 5 4 3 3 2 2 1
n-i 0 1 2 2 3 3 4
交点 0 4 6 7 8 9 10
0 4+0 2+2+2+0 2+2+2+1 3+3+2 3+3+3 4+3 4+4 4+5 4+6
----------------------------------------------------------
n=6
i 6 5 4 3 2 1
n-i 0 1 2 3 4 5
交点 0 4 6 7 8 9 10
0 5+0 4+4+0 4+4+1 3+3+3+0 3+3+3+2 3+3+3+3 2+2+2+2+0 2+2+2+2+3 ...
---------------------------------------------------------------------------------------
n 1 2 2 3 3 3 ...
0 n-1+0 n-2+n-2+0 n-2+n-2+1 n-3+n-3+n-3+0 n-3+n-3+n-3+2 n-3+n-3+n-3+3 ...
总结出上面的规律:
对于n条直线,当有i条平行线时(0<i<n,这个范围比较好说),共有下面多种情况:(数组a为有n-i条线的情况)
i+i+...+i+0=i*(n-i)+0
i*(n-i)+a[1]
i*(n-i)+a[1]
...
n*(n-1)/2
代码
#include<stdio.h>
void find(int b[],int *n,int m)
{//将m插入单调递增的数组中,数组中有相同元素则不插入
int i,j;
for(i=*n -1;i&&m<b[i];i--);
if(m>b[i]&&i==*n-1) b[(*n)++]=m;
else if(m<b[i]&&m!=b[i-1]&&i!=n-1){
for(j=n-1;j>=i;j--) b[j+1]=b[j];
b[j+1]=m;
(*n)++;
}
}
int main()
{
int n,a[21][100]={0},num[20]={1,1,1},i,j,k,t,p;
while(scanf("%d", &n)+1){
for(i=2;i<=n;i++){//i条线
for(num[i]=1,j=1;j<i;j++){//j条非平行线
t=(i-j)*j;//初始交点数
for(k=0;k<num[j];k++){//当前非平行线个数
p=t+a[j][k];
find(a[i],&num[i],p);
}
}
}
for(i=0;i<num[n];i++)
printf("%d ", a[n][i]);
printf("\n");
}
return 0;
}