大数乘除(hdoj1023)
2011-03-13 16:03
218 查看
通过这题深深的理解了算法的重要性。
深深理解了算法没有绝对最优,只有相对,要针对具体情况设计相应的算法,这才是王道!
之前做死的写大数*大数,大数/大数,好不容易写出来,TLE,改成10^10进制,在自己机器上运行居然比10进制的还慢!后来发现是大数/大数出的问题,方法是用减法模拟除法,然后就悲剧了如果是像10^10/2这样很小的数,就这一个数都会TLE.
后来仔细观察其实没必要用大数*大数,大数/大数,只要大数/(小数)就行。然后10^10进制果断0MS过了。因为c[i]=c[i-1]*(4*i-2)/(i+1)
TLE的代码:
0msAC的代码
深深理解了算法没有绝对最优,只有相对,要针对具体情况设计相应的算法,这才是王道!
之前做死的写大数*大数,大数/大数,好不容易写出来,TLE,改成10^10进制,在自己机器上运行居然比10进制的还慢!后来发现是大数/大数出的问题,方法是用减法模拟除法,然后就悲剧了如果是像10^10/2这样很小的数,就这一个数都会TLE.
后来仔细观察其实没必要用大数*大数,大数/大数,只要大数/(小数)就行。然后10^10进制果断0MS过了。因为c[i]=c[i-1]*(4*i-2)/(i+1)
TLE的代码:
#include<iostream> using namespace std ; #define N 60 //every element in array is between 0 and 9 //reverse the data to restore,a0,a1,...,an-1 void mul(int *a,int *b,int *c,int lenA,int lenB,int &lenC){ int i; lenC=lenA+lenB-1;//[lena+lenb-1,lena+lenb] for(i=0;i<=lenC;i++)c[i]=0;//<= not < for the jugde lenD++; for(i=0;i<lenA;i++){ for(int j=0;j<lenB;j++)c[i+j]+=a[i]*b[j]; } for(i=0;i<lenC;i++){ if(c[i]>9){ c[i+1]+=(c[i]/10); c[i]%=10; } } i=lenC; while(i>0&&c[i]==0)i--; lenC=i+1; } //if a>=b return true; bool compare(int *a,int *b,int lenA,int lenB){ if(lenA>lenB&&a[lenA-1]!=0)return true;//zero series else if(lenA<lenB)return false; else{ int i; for(i=lenA-1;i>-1;i--){ if(a[i]>b[i])return true; else if(a[i]<b[i])return false; } return true; } } //a-b*10^(lenA-lenB) //every element in array is between 0 and 9 //we assume a>=b , both a and b are positive //reverse the data to restore,a0,a1,...,an-1 void sub(int *a,int *b,int *c,int lenA,int lenB,int &lenC){ fill(c,c+lenA,0); int i; for(i=0;i<lenB;i++){ c[i]+=(a[i]-b[i]); if(c[i]<0)c[i]+=10,c[i+1]--; } for(i=lenB;i<lenA;i++)c[i]+=a[i]; i=lenA-1; while(i>=1&&c[i]==0)i--;// lenC=i+1; } //we assume a>=b ,both a and b are positive //at last,the rest of a/b is in a //we assume a>=b , both a and b are positive //reverse the data to restore,a0,a1,...,an-1 void div(int *a,int *b,int *c,int lenA,int lenB,int &lenC){ //int &lenA用于求余数,注意a数组值是变化的! lenC=lenA-lenB+1; if(a[lenA-1]<b[lenB-1])lenC--; if(lenC<=0){ lenC=1; c[0]=0; } else{ fill(c,c+lenC,0); int tmp ,len; int i; for(i=lenC-1;i>-1;i--){ while(compare(a+i,b,lenA-i,lenB)){//particular position handle c[i]++; sub(a+i,b,tmp,lenA-i,lenB,len); memcpy(a+i,tmp,len*sizeof(int)); lenA=i; if(len!=1||tmp[0]!=0)lenA+=len; } } } } void itoi(int source,int *des,int &len){ len=0; while(source){ des[len++]=source%10; source/=10; } } int c[101] ,cLen[101]; void catalan(int n){ c[0][0]=1; cLen[0]=1; int convert ,conLen,t ,tLen; for(int i=1;i<=n;i++){ itoi(4*i-2,convert,conLen); mul(convert,c[i-1],t,conLen,cLen[i-1],tLen); itoi(i+1,convert,conLen); div(t,convert,c[i],tLen,conLen,cLen[i]); } } int main(){ catalan(100); int n; while(scanf("%d",&n)!=EOF){ int i; for(i=cLen -1;i>-1;i--)cout<<c [i]; cout<<endl; } return 0; }
0msAC的代码
#include<iostream> using namespace std ; #define LL __int64 #define RADIX 10000000000 //radix=LL_MAX,10位一组,LL*LL<__LL64,用LL存储 #define N 10 //reverse the data to restore,a0,a1,...,an-1 //a*=b void mul(LL *a,int b,int &lenA){ int i; for(i=0;i<lenA;i++)a[i]*=b; for(i=0;i<lenA;i++){ if(a[i]>=RADIX){ a[i+1]+=(a[i]/RADIX); a[i]%=RADIX; } } if(a[lenA])lenA++; for(i=lenA-1;i>0&&(!a[i]);i--); lenA=i+1; } void div(LL *a,int b,int &lenA){ int i; for(i=lenA-1;i>-1;i--){ if(i>0)a[i-1]+=((a[i]%b)*RADIX); a[i]/=b; } for(i=lenA-1;i>0&&(!a[i]);i--); lenA=i+1; } LL c[101] ; int cLen[101]; void catalan(LL n){ c[0][0]=1; cLen[0]=1; for(LL i=1;i<=n;i++){ memcpy(c[i],c[i-1],cLen[i-1]*sizeof(LL)); cLen[i]=cLen[i-1]; mul(c[i],4*i-2,cLen[i]); div(c[i],i+1,cLen[i]); } } void output(LL *a,int lenA){ LL i; LL t ; memcpy(t,a,lenA*sizeof(LL)); printf("%I64d",a[lenA-1]); for(i=lenA-2;i>-1;i--){ LL cnt=10; while(t[i]){ t[i]/=10; cnt--; } while(cnt--)printf("0"); printf("%I64d",a[i]); } } int main(){ catalan(100); LL n; while(scanf("%d",&n)!=EOF){ output(c ,cLen ); cout<<endl; } return 0; }
相关文章推荐
- hdu 1023 Train Problem II----catalan数列.大数乘除
- 【ACM Steps】2.2.6 HDOJ 1023 Train Problem II JAVA解决卡特兰大数问题
- HDOJ1023(卡特兰数+大数乘除法)
- HDOJ1002 HOOJ1042大数基本题 C/C++
- HDoj-1250-Hat's Fibonacci-大数
- 【集训笔记】【大数模板】特殊的数 【Catalan数】【HDOJ1133【HDOJ1134【HDOJ1130
- HDOJ1002题A + B Problem II,2个大数相加
- hdoj 1002 A + B Problem II 【大数A+B】
- HDU 1023 Traning Problem (2) 大数卡特兰数
- HDOJ-1002大数相加
- hdoj 1002 a+b 大数相加 C++
- HDOJ-2054(大数比较)(A == B ?)
- HDOJ 1002 A + B Problem II(大数A+B)
- HDU 1023 Train Problem II 大数打表Catalan数
- HDOJ1261 大数乘除法应用
- hdoj3787 大数A+B
- 【大数问题】 HDOJ 1316 How Many Fibs?
- hdoj-1753-大明A+B(大数)
- HDOJ 1023 Train Problem II
- HDOJ-1753 大明A+B (浮点大数)