NC 四舍五入
题目描述
链接:https://ac.nowcoder.com/acm/contest/20960/1004
来源:牛客网
他在不超过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。
模拟构思
维护两个pos
分别贪心的去扫就行了. 注意判断小数点的位置, 以及进位的情况.
注意在这份实现中要特判没有小数点存在的情况.
Code
#include <bits/stdc++.h>
using namespace std;
#define MAXN 420005
#define F(i, a, b) for(int i=a; i<=b;i++)
#define Fd(i, a, b) for(int i=a;i>=b;i--)
string st;
char s[MAXN];
int n, t, decimalpt = -1, endplace=0;
int main(){
cin>>n>>t; cin>>st;
n = st.length();
F(i, 0, n-1){
if(st[i] == '.'){
decimalpt = i;
continue;
}
s[i+(decimalpt == -1 ? 1:0)] = st[i];
}
s[n+1] = '\0';
// printf("%s, dec = %d\n", s+1, decimalpt);
int pos=decimalpt+1;
for(;pos<=n; pos++){
if(s[pos]-'0'>=5) break;
}
if(pos >n || decimalpt == -1){
cout<<st;
return 0;
}
int pos2 = pos-1;
for(;s[pos2]-'0'==4 && pos2 > decimalpt; pos2--);
if(t>=pos-pos2){
endplace=max(decimalpt, pos2);
}else{
endplace=max(decimalpt, pos-t);
}
// cout<<endplace<<endl;
int epl = endplace;
s[0]='0';
while(s[endplace] +1 == ':'){
s[endplace] = '0';
endplace --;
}
s[endplace]++;
// printf("endplace = %d, %s\n", endplace, s);
#define PRI(f) F(i, (f), decimalpt) cout<<s[i];\
cout<<".";\
F(i, decimalpt+1, endplace) cout<<s[i];
#define PRIV(f) F(i, (f), decimalpt) cout<<s[i];
if(endplace>decimalpt){
if(s[0] == '0'){
PRI(1)
}else{
PRI(0)
}
}else{
if(s[0] == '0'){
PRIV(1);
}else{
PRIV(0);
}
}
}