蓝桥杯 算法提高 高精度乘法 高精压位

来源:互联网 发布:mp4视频格式转换软件 编辑:程序博客网 时间:2024/05/16 10:31
  算法提高 高精度乘法  
时间限制:1.0s   内存限制:256.0MB
    
问题描述
  在C/C++语言中,整型所能表示的范围一般为-231到231(大约21亿),即使long long型,一般也只能表示到-263到263。要想计算更加规模的数,就要用软件来扩展了,比如用数组或字符串来模拟更多规模的数及共运算。
  现在输入两个整数,请输出它们的乘积。
输入格式
  两行,每行一个正整数,每个整数不超过10000位
输出格式
  一行,两个整数的乘积。
样例输入
99
101
样例输出
9999
数据规模和约定
  每个整数不超过10000位

高精压位代码在下面。。。
什么时高精压位呢?
不压位时,逢十进一,a[i]只能保存0-9中的一位,
压4位时,每10000进一,a[i]能保存0-9999中的1-4位。
使用压位时,得先把字符串转换成相应的数组,这个数组应该是压位后的数组,
比如123456789,压四位的话,a[0]=6789,a[1]=2345,a[2]=1,(这里的a[]只是打比方,具体下标再处理)

90分的答案:有一个数据运行超时了。,要再优化一下。。
#include<iostream>#include<string>#include<algorithm>#include<cstring> using namespace std;int v[10000000];int main(){memset(v,0,sizeof(v));string a,b;cin >>a>>b;int alen=a.length(),blen=b.length();string ta(a.rbegin(),a.rend());   //字符串逆序。方便计算。 string tb(b.rbegin(),b.rend());int i,j,k=0;for(i=0;i<alen;i++){k=i;for(j=0;j<blen;j++){v[k+j]+=(ta[i]-'0')*(tb[j]-'0');if(v[k+j]>9){v[k+1+j]+=v[k+j]/10;v[k+j]=v[k+j]%10;}}}if(v[k+j]==0)k--;for(i=k+j;i>=0;i--){if(v[k+j]==0)i--;cout <<v[i];}return 0;}
AC...第一次优化。
#include<iostream>#include<string>#include<algorithm>#include<cstring> using namespace std;int v[10000000];int main(){memset(v,0,sizeof(v));string a,b;cin >>a>>b;int alen=a.length(),blen=b.length();int i,j,k,t;for(i=alen-1,k=0;i>=0;i--,k++){for(j=blen-1,t=0;j>=0;j--,t++){v[k+t]+=(a[i]-'0')*(b[j]-'0');/*if(v[k+t]>9){v[k+1+t]+=v[k+t]/10;v[k+t]=v[k+t]%10;}*/}}             for(i=0;i<k+t;i++){if(v[i]>9){v[i+1]+=v[i]/10;v[i]%=10;}}k--;if(v[k+t]==0)k--;for(i=k+t;i>=0;i--){cout <<v[i];}return 0;}


问了一个大神才知道的..
这里压4位高精,太高的话,小心溢出了。
cpu使用78ms,内存使用1.074mb
//高精压位 #include<iostream>#include<string>#include<algorithm>//#include<cstring>//#include<cstdio>#include<iomanip>#define p 4      //压 4位高精 #define carry 10000      //10的p次方 using namespace std;int v[20000];int x[2600];int y[2600];int main(){ string a,b;cin >>a>>b;int alen=a.length(),blen=b.length();int i,j,k,ta,tb,w;string sa(a.rbegin(),a.rend());       //将字符串逆序. for(i=0,ta=-1;i<alen;i++,w*=10){         //将字符串a化为高精度数组.x[].if(i%p==0){                   //每p位进一 w=1;ta++;}x[ta]+=w*(sa[i]-'0');}string sb(b.rbegin(),b.rend());        //对字符串b处理同上。 for(i=0,tb=-1;i<blen;i++,w*=10){if(i%p==0){w=1;tb++;}y[tb]+=w*(sb[i]-'0');}for(i=0;i<=ta;i++){              //两数相乘; for(j=0;j<=tb;j++){v[i+j]+=x[i]*y[j];v[i+j+1]+=v[i+j]/carry;v[i+j]%=carry;}} int vlen=0;        //找到数组长度。 for(i=ta+tb+2;i>=0;i--){if(v[i]){vlen=i;break;}}for(i=vlen;i>=0;i--){if(vlen==i)cout<<v[i];else{cout <<setw(p)<<setfill('0')<<v[i];  //C++自动补0 }//printf("%0*d",p, v[i]);        //C自动补 0 }return 0;}



原创粉丝点击