【数据布局入门练习DAY-14】 蓝桥杯2024年第十五届省赛真题-R 格式 ...

打印 上一主题 下一主题

主题 1644|帖子 1644|积分 4932

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
文章目录

  

  • 媒介
  • 一、题目
  • 二、解题思路
  • 总结
  
媒介

本次练习内容:

  • 蓝桥杯的预备练习。
  • 练习解题思维。

一、题目
        
小蓝最近在研究一种浮点数的表示方法:R 格式。对于一个大于 0 的浮点数 d,可以用 R 格式的整数来表示。给定一个转换参数 n,将浮点数转换为 R格式整数的做法是:
1. 将浮点数乘以 2n;
2. 四舍五入到最接近的整数。
输入格式

一行输入一个整数 n 和一个浮点数 d,分别表示转换参数,和待转换的浮点数。
输出格式

输出一行表示答案:d 用 R 格式表示出来的值。
样例输入

  1. 2 3.14
复制代码
样例输出

  1. 13
复制代码
二、解题思路

        我信赖很多朋友都和我一样,刚开始是使用<cmath>的pow求2的n次幂,然后用都double里的d乘以2的n次幂的值,末了用round来让它就近取整。但是很抱歉,它对一半。(破防了……)我想了想只能使用string然后加高精度了……。但是这俩东西我不太熟,只能去请教了一下别人的思路来做了。解题代码如下:
  1. #include <iostream>
  2. #include <string>
  3. #include <algorithm>
  4. using namespace std;
  5. // 大整数字符串加法(保证参数都为非负数的字符串)
  6. string addString(const string &a, const string &b) {
  7.     int i = a.size() - 1, j = b.size() - 1;
  8.     int carry = 0;
  9.     string res;
  10.     while(i >= 0 || j >= 0 || carry) {
  11.         int sum = carry;
  12.         if(i >= 0) {
  13.             sum += a[i] - '0';
  14.             i--;
  15.         }
  16.         if(j >= 0) {
  17.             sum += b[j] - '0';
  18.             j--;
  19.         }
  20.         carry = sum / 10;
  21.         res.push_back(char('0' + sum % 10));
  22.     }
  23.     reverse(res.begin(), res.end());
  24.     return res;
  25. }
  26. // 将大整数字符串乘以2
  27. string maxstring(const string &s) {
  28.     int carry = 0;
  29.     string res;
  30.     for (int i = s.size() - 1; i >= 0; i--) {
  31.         int prod = (s[i] - '0') * 2 + carry;
  32.         carry = prod / 10;
  33.         res.push_back(char('0' + prod % 10));
  34.     }
  35.     if(carry) {
  36.         res.push_back(char('0' + carry));
  37.     }
  38.     reverse(res.begin(), res.end());
  39.     return res;
  40. }
  41. // 模拟除以 10^k,由于除数为10的幂,只需去掉末尾 k 位
  42. string Pow(const string &num, int k) {
  43.     if(num.size() <= (unsigned)k) return "0";
  44.     return num.substr(0, num.size() - k);
  45. }
  46. int main(){
  47.     int n;
  48.     string d;
  49.     cin >> n >> d;
  50.     // 找到小数点位置,拆分整数
  51.     int dotPos = d.find('.');
  52.     int k = d.size() - dotPos - 1; // 小数位数
  53.     // 整数 A = 去掉小数点后的数字串
  54.     string A = d.substr(0, dotPos) + d.substr(dotPos + 1);
  55.     // 计算 A * 2^n:重复 n 次乘以 2
  56.     string val = A;
  57.     for(int i = 0; i < n; i++){
  58.         val = maxstring(val);
  59.     }
  60.     // 偏移量 offset = 10^k / 2,等价于 "5" 后面跟 (k-1) 个 '0'(k>=1)
  61.     string offset = (k > 0) ? ("5" + string(k - 1, '0')) : "0";
  62.     // 加上偏移量,完成四舍五入:计算 val + offset
  63.     string sumVal = addString(val, offset);
  64.     // 除以 10^k,即将字符串末尾 k 位去掉,得到最后的整数
  65.     string result = Pow(sumVal, k);
  66.     cout << result << "\n";
  67.     return 0;
  68. }
复制代码


总结

        本日的题目让我感觉自己拿到想要的目标结果还有一定隔断,但是我信赖只要对峙做下去就会得到胜利的果实,本日没有其他的感受,已经想麻了……。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

饭宝

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表