链接:https://ac.nowcoder.com/acm/problem/200369
来源:牛客网

题目描述

qdgg只能四舍五入t次。请帮助qdgg找到他在不超过t次四舍五入可获得的最高成绩。请注意,他可以选择不使用全部t次机会。此外,他甚至可以选择完全不对成绩进行四舍五入。
在这个问题中,使用经典的舍入规则:将数字四舍五入到第n个数字时,必须先看一下数字n + 1,如果小于5,则第n个数字将保持不变,而所有后续数字替换为0。否则,如果n + 1位数大于或等于5,则位置n处的位数将增加1(如果此位数等于9,这也可能会更改其他一些位数),并且随后的所有位数数字将替换为0。最后,所有尾随的零将被丢弃。
例如,如果将数字1.14舍入到小数点后第一位,则结果为1.1,而如果将1.5舍入到最接近的整数,则结果为2。四舍五入到小数点后第五位的数字1.299996121将得出数字1.3。

输入描述:

输入的第一行包含两个整数n和t(1≤b≤200000 1≤t≤10 9)表示小数(含小数点)的长度以及四舍五入的次数。
第二行为一个字符串表示qdgg的初始分数。

输出描述:

一行表示qdgg能得到的最高分数(请勿输出尾零)

咱就说这个题不难,但是该踩的坑我是一个没少踩。
#关注点#:让他的成绩可以在小数点后的任意位置四舍五入。
根据这个关注点可以知道,这里我们不用从后先前逐个进行四舍五入。为了减少次数,我们可以从小数点后的第一位开始,假设在位置i+1有五入的处理,这里有以下几种情况需要考虑:
1、若i 的值是四,那么可以继续五入并继续检查i-1是否为4,如果为4那么继续进行五入。
2、i的值为小数点,那么将此位置为结束位。同时查看i-1位即小数点前一位的值
b.i-1的值不为9,该位加1.
a.i-1位的值为9,那么将该位置置0,向前进1;如果首位为9加1那么先输出一个1在输出数字。

#include<iostream>
#include<string>
using namespace std;
int main(){
   
    string str;
    int n,t;
    cin >> n >> t >> str;
   int pos = str.find('.');
    if(pos == str.npos) {
     //易错点2
        cout << str;
        return 0;
     }
    for(int i = pos+1; i < n; i++){
   
        if(str[i] >= '5'){
   
            str[i] = 'x';
            t--;
            i--;
            while(str[i] == '4'&& t){
   
                 str[i] = 'x';  //用x代表结束位,原本是用\0 : 易错点1
                t--;
                i--;
            }
            if(str[i] == '.'){
   
                  str[i] = 'x';
                i--;
                while(str[i] == '9'){
   
                    str[i] = '0';
                    i--;
                }
                if(i == -1) cout <<'1';
                else str[i]  += 1;
            }
            else str[i] += 1;
            break;
        }
    }
    for(int i = 0; i < str.length(); i++){
   
        if(str[i] == 'x') break;
        cout << str[i];
    }
}

#易错点#
1、string类型中‘\0’不作为结束标志,相反可以作为一个字符存在于string中
2、string 中的npos可以看做实数但是不意味着它和-1等价,不能与整数进行比较加减。否则可能出现数组越界错误