题目是杨辉三角的分布,形如:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
etc........
上层的两个数相加可得下层的一个数,呈类似Fib函数。
问题来了,求第K层上的第L个数是多少?(其实还要求得出第K层总和,但是这个稍微简单)
关键K层: 1 < K <1000
×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
我一开始的思路是,用递归。
int find(int row, int i){
int x=0;
if(i ==2 || i== row-1){
res +=row-1;
return 0;
}
if(i == 1 || i==row ){
res += 1;
return 0;
}
if(row == 3){
res +=2;
return 0;
}
if(row == 4){
res +=3;
return 0;
}
if(row == 5 && (i==2 || i==4)){
res +=4;
return 0;
}
if(row == 5 && i == 3){
res +=6;
return 0;
}
for(x=row-1;x>=i-1;x--){
find(x,i-1);
}
return 0;
}
但是后来想到,如果求Fib(n)用递归的效率几乎是渣,那这个如果递归几乎同等为渣。
于是,于是我凌乱了,在考试的时候智商直接自由落体为0。。。。。因为当时我还在调试优化递归的效率
我同时还想到建二维数组,但是时间原因并没有实现过。
楼主在完全落败后,回家思考了下这个问题,如果不递归,只能像Fib一样,一个一个的求出值来,方便后续的计算,而不是每次都得递归到K=2
但是K=1000,这是个很大的map,二维数组肯定不行,,,,,于是我想到了一维数组。
于是我想到了,某个计算机大牛说过,程序到了最后,都是数据结构的事情,如果决定了用什么样的数据结构来处理,基本上程序就出来了。
后来我看看写出来的程序,是这样的。基本上没有技巧的东西,用什么样的数据方式,决定了你的思路和效率。
后来我的代码就变成这样。。。。。效率确实大大提高了。。。。。
#include <stdio.h>
int index(int x){
//count the number of pre K Line, how
//many digits we got, used as base_index
int i;
int sum=0;
for(i=1;i<x;i++)
sum += i;
return sum;
}
int find(int array[], int i, int j){
//find the specific digit.
//base_index + j(j is the j th number of K line)
int sum = index(i);
return array[sum+j-1];
}
void build_data(int array[], int i){
//if we need i line totally, we build the datas needed
//the only bottleneck for efficiency.
//store the data in 1 dimention array
int x,y;
int base=0;
for(x=1;x<=i;x++){
for(y=1;y<=x;y++){
if(y==1 || y==x)
array[base+y-1] = 1;
else{
array[base+y-1] = array[base+y-1-x]+array[base+y-1-x+1];
if(array[base+y-1]>10000)
array[base+y-1] %= 10000;//in case overflow, division by 10000
}
}
base += x;//similar to index(int i)
}
}
int a[500000]={0};// store 1000!, needs 500000 numbers. stored as global
void main(void){
int K=7;
int L=5;
int ret;
build_data(a,K);
ret = find(a,K,L);
printf("%d\n",ret);
}
PS:
后来有人说可以用求概率的那个C来求取,公式是
C 上面是L-1 下面是K-1,有兴趣可以试试。
但是如果有时间限制,一般想不到这个方法的。