P10425 [蓝桥杯 2024 省 B] R 格式

题目描述

小蓝最近在研究一种浮点数的表示方法:R 格式。对于一个大于 0 的浮点数 d,可以用 R 格式的整数来表示。给定一个转换参数 n,将浮点数转换为 R 格式整数的做法是:

  1. 将浮点数乘以 2n。

  2. 四舍五入到最接近的整数。

输入格式

一行一个整数 n 和一个浮点数 d。

输出格式

一行一个整数表示 d 用 R 格式表示出的值。

输入输出样例

输入 #1复制

2 3.14

输出 #1复制

13

说明/提示

样例 1 解释

3.14×22=12.56,四舍五入后为 13。

数据规模与约定

用 t 表示将 d 视为字符串时的长度。

  • 对于 50% 的数据,保证 n≤10,t≤15。

  • 对于全部的测试数据,保证 1≤n≤1000,1≤t≤1024,保证 d 是小数,即包含小数点

暴力解法(通过50%)

#include<bits/stdc++.h>
using namespace std;
int n;
double d;
int main()
{
    cin>>n>>d;
    double ans=d*pow(2,n);
    long long res=round(ans);
    cout<<res<<endl;
    return 0;
}

计算平方的函数pow(2,n)

四舍五入函数round(ans);

AC解法(通过100%)

#include <bits/stdc++.h>
using namespace std;

const int N=1000005;

int n;
int a[N];
int len;
int mt;

int main() {
    scanf("%d",&n);
    string d;
    cin>>d;
    bool flag=false;
    for (int i=d.size()-1;~i;--i) {
        if (d[i]=='.') {
            flag=true;
            continue;
        }
        a[++len]=d[i]-'0';
        if (!flag) mt++;
    }
    for (int i=1;i<=n;++i) {
        int j=1,jw=0;
        while (j<=len || jw) {
            a[j]<<=1;
            a[j]+=jw;
            jw=a[j]/10;
            a[j]%=10;
            ++j;
        }
        --j;
        len=j;
    }
    if (a[mt]>=5) {
        int i=mt+1;
        a[i]++;
        while (a[i]>=10) {
            a[i+1]+=a[i]/10;
            a[i]%=10;
            ++i;
        }
    }
    int t=N-1;
    while (t>=mt+1 && !a[t]) t--;
    if (t<mt+1) puts("0");
    else {
        for (int i=t;i>=mt+1;--i) {
            printf("%d",a[i]);
        }
    }
    return 0;
}

下面有详细解释注释:

#include <bits/stdc++.h>
using namespace std;

// 定义数组的最大长度
const int N = 1000005;

// n 表示要将输入的小数乘以 2 的 n 次幂
int n;
// 用于存储小数的每一位数字,整数部分和小数部分一起存储
int a[N];
// len 记录存储在数组 a 中的数字的长度
int len;
// mt 记录小数点的位置
int mt;

int main() {
    // 读取输入的整数 n
    scanf("%d", &n);
    // 用于存储输入的小数
    string d;
    cin >> d;
    // 标记是否遇到小数点
    bool flag = false;
    // 从输入小数的末尾开始向前遍历
    for (int i = d.size() - 1; ~i; --i) {
        // 如果当前字符是小数点
        if (d[i] == '.') {
            // 标记遇到了小数点
            flag = true;
            continue;
        }
        // 将字符转换为数字并存储到数组 a 中,同时长度加 1
        a[++len] = d[i] - '0';
        // 如果还没遇到小数点,说明是整数部分,mt 加 1
        if (!flag) mt++;
    }
    // 进行 n 次乘以 2 的操作
    for (int i = 1; i <= n; ++i) {
        int j = 1, jw = 0;
        // 模拟乘法运算,处理每一位数字
        while (j <= len || jw) {
            // 当前位数字乘以 2
            a[j] <<= 1;
            // 加上进位
            a[j] += jw;
            // 计算新的进位
            jw = a[j] / 10;
            // 当前位数字取模 10
            a[j] %= 10;
            // 处理下一位
            ++j;
        }
        // 调整数组长度
        --j;
        len = j;
    }
    // 判断小数部分的第一位是否大于等于 5,进行四舍五入
    if (a[mt] >= 5) {
        int i = mt + 1;
        // 小数部分进位
        a[i]++;
        // 处理进位
        while (a[i] >= 10) {
            a[i + 1] += a[i] / 10;
            a[i] %= 10;
            ++i;
        }
    }
    // 去除整数部分末尾的 0
    int t = N - 1;
    while (t >= mt + 1 && !a[t]) t--;
    // 如果整数部分没有非零数字,输出 0
    if (t < mt + 1) puts("0");
    else {
        // 输出整数部分
        for (int i = t; i >= mt + 1; --i) {
            printf("%d", a[i]);
        }
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值