误点一:容易固化思维理解为从最后一位小数向前四舍五入

误点二:会缺少判断没有小数点的可能

思路:寻找小数点后第一个可以五入的数(无论后面如何四舍五入,只要第一个能五入,就绝对比后面的大),再特判前一个数字是否为9

注意

1.整数部位是否会多出一位,例如9.9进为10,99.9进为100等等

2.可能存在没有小数点的情况

#include<bits/stdc++.h>

using namespace std;

const int N = 2e5 + 10;
char y[N];

int main()
{
	int n, t;
	cin >> n >> t;
	string s;
	cin >> s;
	int m = 0, res = 0, ans = 0, x = s.size() - 1, c = 0;
	for(int i = 1; i < s.size(); i ++ )
	{
		if(s[i] == '.') m = i;//找到.所在位置
	}
	for(int i = m+1; i < s.size(); i ++ )
	{
		if(s[i] >= '5')
		{
			c = i;//找到小数点后第一个能五入的数
			break;
		}
	}
	if(c == 0 || m == 0)//小数点后没有能五入的数||不存在小数点
	{
		for(int i = 0; i < s.size(); i ++ ) cout << s[i];
        return 0;
	}
	
	for(int i = c; i > m; i --)
	{
		if(res == 1)//后一位进一
		{
			if(s[i] == '9')//特判9
			{
				res = 1;//向前进一
				s[i] = '0';
			}
			else
			{
				s[i] = char(s[i] + 1);
				res = 0;
			}
		}
		if(ans == t && res == 0) break;
		
		if(s[i] >= '5' && ans < t)
		{
			if(s[i] == '9')
			{
				s[i] = '0';
			}
			else s[i] = char(s[i] + 1);
			
            res = 1;//五入
			ans ++;
			x = i-1;	//记录最后能够五入的数的位置的前一位
		}
	}
    int b = 0;
	if(res == 1)//整数部位进一
	{
		for(int i = m-1; i >= 0; i -- )//对整数部位进行运算
		{
			if(res == 1)
			{
				if(s[i] == '9')
				{
					s[i] = '0';
					res = 1;
                    if(i == 0) b = 1;//整数部位多一位的情况,是s[0]原先为9,现变为0,进一位
				}
				else
				{
					s[i] = char(s[i] + 1);
					res = 0;
				}
			}
		}
	}
	if(x == m) x --;//如果最后五入的是小数点后一位,则最后只需要整数部分
    int a = 0, mal = 0;
	for(int i = x; i >= 0; i -- )
    {
        if(a == 0)//去除尾0
        {
            if(x>m && s[i] != '0') a = 1;
            else if(x<m) a = 1;
        }
        if(a == 1)
        {
            y[mal ++ ] = s[i];//存入新字符串数组中
        }
    }
    if(b == 1) cout << b;//输出整数部位多出的一位
    for(int i = mal - 1; i >= 0; i --) cout << y[i];//新字符串倒序输出
	
	return 0;
}