Efim与奇怪的成绩
作者:互联网
【题目描述】
众所周知,每当我们看见自己糟糕的成绩时,我们总希望以奇怪的方式将其四舍五入。
Efim同样如此。在晴朗的一天,Efim拿到了他的成绩X,他希望通过最多m次四舍五入使他的成绩最大化(每一次四舍五入舍掉的的位置任意,但只能在小数部分,不能在整数部分)。注意:m次可以不用完。
例如1.14四舍五入掉最后一位后为1.1。1.5四舍五入后为2。1.299四舍五入后为1.3。
【输入】
第一行两个整数n和m,n表示X的字符数。1<=n<=200000,1<=m<=1000000000。
第二行一个实数X,表示Efim的成绩。
【输出】
一个实数X,表示他的成绩的可能的最大值,Efim不希望他的成绩有后缀零。
【输入样例1】
6 1
10.245
【输出样例1】
10.25
【输入样例2】
6 2
10.245
【输出样例2】
10.3
【输入样例3】
3 100
9.2
【输出样例3】
9.2
【提醒】
这道题同学们应追求满分,而不是满足于70,8090分。
时间限制 : 1s
空间限制 : 256M
看着比赛的最后一句话,就知道肯定是一个细节很多的题(不然一般不会有70,80,90这三个这么接近的数字)
首先,肯定是在越前面四舍五入越好,因为比较数位是从前往后一位一位比较的。难道这道题就这样做完了?
不。如果是样例10.245这种情况,五入了还可以再次五入,那就不行了。同时还有出现9进位导致在此进位的情况。所以我们要不断地往前面找,如果又可以五入并且还有次数那就五入,如果有9可以进位那就进位。但是细节还是有点多的。首先五入只能在小数点后,同时进位时如果跨过了小数点那么要加在整数上,如果小数全部进完了那就要省略小数点。具体的细节还是看代码吧,细节真的很多。
#include<iostream>
#include<cstdio>
using namespace std;
const int N=2e5+5;
char s[N];
int n,m,f1,st;
int main()
{
scanf("%d%d%s",&n,&m,s+1);
s[0]='0';
for(int i=1;i<=n;i++)
{
if(f1&&s[i]>='5')
{
st=i;
for(int j=i+1;j<=n;j++)
s[j]=0;
break;
}
if(s[i]=='.')
f1=1;
}
if(!st)
{
cout<<(s+1)<<endl;
return 0;
}
for(int i=st;i!=0;i--)
{
if(s[i]!='.')
{
if(s[i]=='9'+1)
{
s[i]='0';
if(s[i-1]!='.')
s[i-1]++;
else
s[i-2]++;
}
if(s[i]>='5'&&m&&f1)
{
if(s[i-1]!='.')
s[i-1]++;
else
s[i-2]++;
m--,s[i]=0;
}
}
else
f1=0;
}
for(n=0;s[n+1];++n);
if(s[n]=='.')
s[n]=0;
if(s[0]=='0')
printf("%s",s+1);
else
printf("%s",s);
return 0;
}
可以比赛调对的人真的很强。
标签:四舍五入,五入,int,样例,成绩,奇怪,进位,Efim 来源: https://www.cnblogs.com/mekoszc/p/16120010.html