|
|
问题描述: 参加任何一项比赛,都会涉及到排名统计问题,由此可见排名统计是多么的重要.这里假设有一项比赛,共有n(1<=n<=200)个人参加,那么请问共有多少种不同的排名(注意:可以很多参赛者在同一个名次,即参赛者名次可以并列)?
数据输入n,输出为不同的排名总数.
如输入
1
2
3
输出为
1
3
13
//程序的性能还不行,算法基本没问题了
==================code================
/**
*Copyright (C) aprin at Xiamen University
*2005-4-24
*/ #include <stdio.h> #define MAX_N 200 #define MAX_LEN 1000
int cheng(int *a1, int len_a1, int *a2, int len_a2); int c_fun(int n, int r, int *c) { int i, j, k, len, temp[3], len_temp, shang[MAX_LEN], len_shang;
/*计算pr/n*/ len=1; c[0]=1; for(i=0; i<r; i++) { j=n-i; len_temp=0; while(j!=0) { temp[len_temp]=j%10; len_temp++; j/=10; } len=cheng(c, len, temp, len_temp); }
/*/r!*/ for(i=0; i<MAX_LEN; i++) shang[i]=0; for(i=2; i<=r; i++) { int temp=len-1, yushu;
len_shang=0; yushu=c[temp]; while(temp>=0) { shang[len_shang]=yushu/i; len_shang++; yushu%=i; temp--; yushu=yushu*10+c[temp]; } /*ji suan du yu de 0*/ k=0; while(shang[k]==0) k++; /*倒转,转移*/ for(j=0; j<MAX_LEN; j++) if(j<(len_shang-k))/* 实际的长度*/ c[j]= shang[len_shang-1-j]; else c[j]= 0; len= len_shang-k; }
return len; } int cheng(int *a1, int len_a1, int *a2, int len_a2) { int temp[MAX_LEN], i, j;
for(i=0; i<MAX_LEN; i++) temp[i]=0; for(i=0; i<len_a2; i++) { for(j=0; j<len_a1; j++) { temp[i+j]=temp[i+j]+a1[j]*a2[i]; temp[i+j+1]=temp[i+j+1]+temp[i+j]/10; temp[i+j]=temp[i+j]%10; } if(temp[i+len_a1]>10) {/*ke neng cun zai de zui gao wei chu li*/ temp[i+len_a1+1]=temp[i+len_a1+1]+temp[i+len_a1]/10; temp[i+len_a1]=temp[i+len_a1]%10; } } i=MAX_LEN-1; while(temp[i]==0) i--; for(j=0; j<MAX_LEN; j++) a1[j]=temp[j]; return i+1; } int add(int *a1, int len_a1, int *a2, int len_a2) { int i,len;
len=(len_a1>len_a2)?len_a1:len_a2; for(i=0; i<len; i++) { a1[i+1]+=(a1[i]+a2[i])/10; a1[i]=(a1[i]+a2[i])%10; } len=MAX_LEN; while(a1[len-1]==0) len--; return len+1; } int ok(int *renshu, int i, int n) { int tot, j;
tot=0; for(j=0; j<=i; j++) tot+=renshu[j]; return tot==n; } void output(int *result, int len) { int i;
for(i=len-2; i>=0; i--) printf("%d", result[i]); putchar('\n'); } int main(void) { int n, i, j, k; int renshu[MAX_N]; int result[MAX_LEN], len;
scanf("%d", &n);
for(i=0; i<MAX_LEN; i++) result[i]=0; len=0;
for(i=0; i<n; i++) { for(j=0; j<=i; j++) renshu[j]=1; do { if(ok(renshu, i, n)) { int result_mid[MAX_LEN], len_mid, temp, total_temp;
len_mid=1; result_mid[0]=1; total_temp=n; for(temp=0; temp<i; temp++) { int zuhe[MAX_LEN], len_zuhe;
len_zuhe=c_fun(total_temp, renshu[temp], zuhe); total_temp-=renshu[temp]; len_mid=cheng(result_mid, len_mid, zuhe, len_zuhe); } len=add(result, len, result_mid, len_mid); } renshu[0]++; for(j=0; j<i; j++) if(renshu[j]>(n-i)) { renshu[j+1]++; renshu[j]=1; } } while(renshu[i]<=(n-i)); }
output(result, len); getch(); return 0; }
|
|