Java教程

Efim与奇怪的成绩

本文主要是介绍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;
}

可以比赛调对的人真的很强。

这篇关于Efim与奇怪的成绩的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!