您的位置:首页 > 其它

南邮 OJ 1218 标准2维表问题

2015-08-05 11:11 211 查看


标准2维表问题

时间限制(普通/Java) : 1000 MS/ 3000 MS          运行内存限制 : 65536 KByte
总提交 : 183            测试通过 : 30 

比赛描述

设n 是一个正整数。2xn的标准2维表是由正整数1,2,…,2n 组成的2xn 数组,该数组的每行从左到右递增,每列从上到下递增。2xn的标准2维表全体记为Tab(n)。例如,当n=3时Tab(3)如下:



给定正整数n,计算Tab(n)中2´n的标准2 维表的个数。

输入

输入的第一行有1个正整数n 

输出

输出计算出的Tab(n)中2xn的标准2维表的个数 

样例输入

3

样例输出

5

提示

 

题目来源

算法设计与实验题解

/* 成功打印 catalan[10000];
#include<iostream>
#define MAX_N 10001

int a[MAX_N][10001]; //a[i][j] 第 i 个 catalan 数的第 j 位
int len;

int main(){
int i,j,temp;
a[0][0] = a[1][0] = 1;
len = 1;
for(i=2;i<MAX_N;i++){
for(j=0;j<len;j++){
temp = a[i][j] + a[i-1][j]*(4*i-2);
a[i][j+1] = temp/10;
a[i][j] = temp%10;
}
while(a[i][len]){
a[i][len+1] = a[i][len]/10;
a[i][len] %= 10;
len++;
}
for(j=len-1;j>0;j--){
a[i][j-1] += a[i][j]%(i+1)*10;
a[i][j] /= (i+1);
}
a[i][0] /= (i+1);
while(!a[i][len-1]){
len--;
}
}
printf("catalen %d,len = :%d\n",MAX_N-1,len);
for(j=len-1;j>=0;j--){
printf("%d",a[MAX_N-1][j]);
}
printf("\n");
}
*/

/* Memory Limit Exceed
#include<iostream>
#define MAX_N 10001

int a[MAX_N][10001]; //a[i][j] 第 i 个 catalan 数的第 j 位
int len;

int main(){
int i,j,temp,n;
a[0][0] = a[1][0] = 1;
len = 1;
scanf("%d",&n);
if(n==0||n==1){
printf("1\n");
}
for(i=2;i<=n;i++){
for(j=0;j<len;j++){
temp = a[i][j] + a[i-1][j]*(4*i-2);
a[i][j+1] = temp/10;
a[i][j] = temp%10;
}
while(a[i][len]){
a[i][len+1] = a[i][len]/10;
a[i][len] %= 10;
len++;
}
for(j=len-1;j>0;j--){
a[i][j-1] += a[i][j]%(i+1)*10;
a[i][j] /= (i+1);
}
a[i][0] /= (i+1);
while(!a[i][len-1]){
len--;
}
}
for(j=len-1;j>=0;j--){
printf("%d",a
[j]);
}
printf("\n");
}
*/

/* 107MS
#include<iostream>
int a[10001];
int len;

int main(){
int i,j,temp,n;
a[0] = 1;
len = 1;
scanf("%d",&n);
if(n==0||n==1){
printf("1\n");
return 0;
}
for(i=2;i<=n;i++){
for(j=0;j<len;j++){
a[j] *= (4*i-2);
}
for(j=0;j<len;j++){
a[j+1] += a[j]/10;
a[j] %= 10;
}
while(a[len]){
a[len+1] = a[len]/10;
a[len] %= 10;
len++;
}
for(j=len-1;j>0;j--){
a[j-1] += a[j]%(i+1)*10;
a[j] /= (i+1);
}
a[0] /= (i+1);
while(!a[len-1]){
len--;
}
}
for(j=len-1;j>=0;j--){
printf("%d",a[j]);
}
printf("\n");
}
*/

/* 10 MS
//catalan(n)=2n*(2n-1)*…(n+2)/n!
//考虑n=1的特殊情况 catalan(n)=2n*(2n-1)*…(n+2)(n+1)/(n+1)!
#include<iostream>

int getPrimes(int *p, int maxN){ //取得不大于maxN的所有素数,存放于数组p[]中,个数通过函数值返回
bool *flag = new bool[maxN+1];
int i,j,count;
memset(p,0,maxN<<2);
for(i=2;i<=maxN;i++){
flag[i] = 1;
}
for(i=4;i<=maxN;i+=2){
flag[i] = 0;
}
for(i=3;i<=maxN;i++){
if(flag[i]){
for(j=i<<1;j<=maxN;j+=i){
flag[j] = 0;
}
}
}
count = 0;
for(i=2;i<=maxN;i++){
if(flag[i]){
p[count++] = i;
}
}
return count;
}

//将 first*(first+1)*……*last 的乘积,转换成素数的幂表示
//prime为素数表,primeNo为素数个数
void makeProductToPrimes(int first,int last,int *result,int *prime,int primeNo){
int i,j,k;
first--;
memset(result,0,primeNo<<2);
for(k=0;k<primeNo;k++){
result[k] = 0;
i = first;
j = last;
while(i!=j){
i /= prime[k];
j /= prime[k];
result[k] += (j-i);
}
}
}

//prime[]:素数表
//primeNo:素数个数
//numerator[]:每个素数的幂
//result[]:转换成的结果
int primeToNum(int *prime, int primeNo, int *numerator, int *result, int maxLen){
int i,j,k,len;
memset(result,0,maxLen<<2);
result[0] = 1;
len = 1;
for(i=0;i<primeNo;i++){
for(j=0;j<numerator[i];j++){
for(k=0;k<len;k++){
result[k] *= prime[i];
}
for(k=0;k<len;k++){
if(result[k]>10){
result[k+1] += result[k]/10;
result[k] %= 10;
}
}
while(result[len]){
result[len+1] = result[len]/10;
result[len] %= 10;
len++;
}
}
}
return len;
}

void printNum(int *p, int len){
for(int i=len-1;i>=0;i--){
printf("%d",p[i]);
}
printf("\n");
}

void catalan(int n){
int primeNo,i,len; //primeNo素数个数
int *prime = new int[n<<1]; //不超过2n素数表
primeNo = getPrimes(prime,n<<1);
int *numerator = new int[primeNo]; //分子中每个素数的幂
int *denominator = new int[primeNo]; //分母中每个素数的幂
makeProductToPrimes(n+1,n<<1,numerator,prime,primeNo);
makeProductToPrimes(1,n+1,denominator,prime,primeNo);
for(i=0;i<primeNo;i++){
numerator[i] -= denominator[i];
}
int *result = new int
;
len = primeToNum(prime,primeNo,numerator,result,n);
printNum(result,len);
delete[] result;
delete[] denominator;
delete[] numerator;
delete[] prime;
}

int main(){
int n;
while(scanf("%d",&n)==1){
catalan(n);
}
}
*/

// 4 MS
#include<iostream>
#define LIMIT 10000 //大数相乘,每个int存放4位十进制数,太大的话会越界,太小的话处理会慢
int getPrimes(int *p, int maxN){ //取得不大于maxN的所有素数,存放于数组p[]中,个数通过函数值返回
bool *flag = new bool[maxN+1];
int i,j,count;
memset(p,0,maxN<<2);
for(i=2;i<=maxN;i++){
flag[i] = 1;
}
for(i=4;i<=maxN;i+=2){
flag[i] = 0;
}
for(i=3;i<=maxN;i++){
if(flag[i]){
for(j=i<<1;j<=maxN;j+=i){
flag[j] = 0;
}
}
}
count = 0;
for(i=2;i<=maxN;i++){
if(flag[i]){
p[count++] = i;
}
}
return count;
}

//将 first*(first+1)*……*last 的乘积,转换成素数的幂表示
//prime为素数表,primeNo为素数个数
void makeProductToPrimes(int first,int last,int *result,int *prime,int primeNo){
int i,j,k;
first--;
memset(result,0,primeNo<<2);
for(k=0;k<primeNo;k++){
result[k] = 0;
i = first;
j = last;
while(i!=j){
i /= prime[k];
j /= prime[k];
result[k] += (j-i);
}
}
}

//prime[]:素数表
//primeNo:素数个数
//numerator[]:每个素数的幂
//result[]:转换成的结果
int primeToNum(int *prime, int primeNo, int *numerator, int *result, int maxLen){
int i,j,k,len;
memset(result,0,maxLen<<2);
result[0] = 1;
len = 1;
for(i=0;i<primeNo;i++){
for(j=0;j<numerator[i];j++){
for(k=0;k<len;k++){
result[k] *= prime[i];
}
for(k=0;k<len;k++){
if(result[k]>LIMIT){
result[k+1] += result[k]/LIMIT;
result[k] %= LIMIT;
}
}
while(result[len]){
result[len+1] = result[len]/LIMIT;
result[len] %= LIMIT;
len++;
}
}
}
return len;
}

void printNum(int *p, int len){
int i,j;
for(j=LIMIT/10;j;j/=10){
if(p[len-1]%(j*10)/j){
break;
}
}
while(j){
printf("%d",p[len-1]%(j*10)/j);
j /= 10;
}
for(i=len-2;i>=0;i--){
for(j=LIMIT/10;j;j/=10){
printf("%d",p[i]%(j*10)/j);
}
}
printf("\n");
}

void catalan(int n){
int primeNo,i,len; //primeNo素数个数
int *prime = new int[n<<1]; //不超过2n素数表
primeNo = getPrimes(prime,n<<1);
int *numerator = new int[primeNo]; //分子中每个素数的幂
int *denominator = new int[primeNo]; //分母中每个素数的幂
makeProductToPrimes(n+1,n<<1,numerator,prime,primeNo);
makeProductToPrimes(1,n+1,denominator,prime,primeNo);
for(i=0;i<primeNo;i++){
numerator[i] -= denominator[i];
}
int *result = new int
;
len = primeToNum(prime,primeNo,numerator,result,n);
printNum(result,len);
delete[] result;
delete[] denominator;
delete[] numerator;
delete[] prime;
}

int main(){
int n;
while(scanf("%d",&n)==1){
catalan(n);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  南邮OJ ACM 标准2维表