解题思路:
作为比赛的第二道大题 这个还是有点难度的,数据量这么大 就是明摆考察高精度了。2^1000 大概是10的300次方 10e300*10e1024 位数在两千位以内 所以不用考虑内存不够。
这里给出两种解法 一个是使用数组 一个是使用队列。使用数组需要多考虑一下n的边界。
因为有小数的情况,所以需要记录一下小数点的位置(或者说是小数占几位),无论怎么乘小数位是不会变的,因为每次*2 所以整数位最多上进1位。
详见代码:
#include <bits/stdc++.h> using namespace std; int A[10010],B = 2; int n=0; void mul(int A[]) { int t=0; // 用于存储进位 for(int i=0; i<n; i++) { A[i]=(A[i]*B) + t; t=A[i]/10; A[i]%=10; } // 如果有进位 if(t!=0) { A[n]=t; n++; } } int main() { int N; scanf("%d",&N); // 输入需要乘以的次数 string s; cin>>s; // 输入浮点数 int flag=0; for(int i=s.size()-1; i>=0; i--) { if(s[i]=='.') { flag=s.size()-1-i; // 记录小数点的位置 continue; } else { A[n]=(s[i]-'0'); n++; } } while(N--) { mul(A); // 执行乘法操作 } // 注意 此时为倒序储存 3.14为413 所以起始位i=n-1 十分位为 flag-1(数组有下标0) // 判断是否需要四舍五入 if(A[flag-1]>=5) { int t=1; // 末尾+1 注意i=flag for(int i=flag; i<n; i++) { A[i]=A[i]+t; t=A[i]/10; A[i]%=10; } if(t!=0) { A[n]=t; n++; } } // 直接打印 for(int i=n-1; i>=flag; i--) { cout<<A[i]; } return 0; }
解法二:
使用stl库里面的队列 有队列就不用考虑n的位置问题 不过不能像数组一样直接获得十位数判断四舍五入。
#include <bits/stdc++.h> using namespace std; // 用于模拟大整数的乘法,每次乘以2 void mul(vector<int> &ver) { int t=0; // 用于存储进位 for(auto &x:ver) { x=x*2+t; // 当前位乘以2并加上之前的进位 t=x/10; // 计算新的进位 x=x%10; // 更新当前位的值 } if(t) ver.push_back(t); // 如果还有进位,则添加到vector的末尾 } int main() { int n; scanf("%d",&n); // 输入需要乘以的次数 string s; cin>>s; // 输入浮点数 reverse(s.begin(),s.end()); // 反转字符串,这样小数的处理会变得更简单 vector<int> ver; // 存储每一位的整数值 int flag=0; for(int i=0; i<s.size(); i++) { if(s[i]=='.') { flag=i; // 记录小数点的位置 continue; } else { ver.push_back(s[i]-'0'); // 将字符转换为数字并添加到vector中 } } while(n--) { mul(ver); // 执行乘法操作 } reverse(ver.begin(),ver.end()); // 再次反转,恢复原始顺序 int bak=-1; while(flag--) { bak=ver.back(); // 从小数点开始,逐个移除位 ver.pop_back(); } // 如果最后一位(被移除的小数部分的最后一位)大于等于5,则进行四舍五入 if(bak>=5) { reverse(ver.begin(),ver.end()); int flag=1; for(int i=0; i<ver.size(); i++) { ver[i]+=flag; flag=ver[i]/10; ver[i]=ver[i]%10; } if(flag) { ver.push_back(flag); } reverse(ver.begin(),ver.end()); } for(auto x:ver) { printf("%d",x); // 输出结果 } return 0; }
ps:再写一个骗分的代码 就是使用double无视位数问题,double最大可达10的三百多次方 和一千位比起来小了点 但是应该可以过50%的测试点(此代码无法通过全部测试点!!) 不过能得一分是一分。
#include <bits/stdc++.h> using namespace std; int main() { int n; double d; cin>>n>>d; d = round(pow(2,n)*d); printf("%.0lf\n",d); return 0; }
0.0分
19 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复