误点一:容易固化思维理解为从最后一位小数向前四舍五入
误点二:会缺少判断没有小数点的可能
思路:寻找小数点后第一个可以五入的数(无论后面如何四舍五入,只要第一个能五入,就绝对比后面的大),再特判前一个数字是否为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;
}