四舍五入(分析)

emmm,刷的一道比较有意思的题,确实是眼界打开了,我这里分析一下。(代码非原创)

四舍五入是个好东西。比如你只考了45分,四舍五入后你是50分再四舍五入你就是满分啦!qdgg刚考完拓扑。成绩十分不理想。但老师觉得他每天都很认真的听课很不容易。于是决定给他一个提高成绩的机会:让他的成绩可以在小数点后的任意位置四舍五入(也可以四舍五入为最接近的整数)。
但是这是有限制的。qdgg只能四舍五入t次。请帮助qdgg找到他在不超过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。

输入描述:

输入的第一行包含两个整数n和t(1≤b≤2000001 \leq b \leq 2000001≤b≤200000,1≤t≤1091\leq t \leq 10^91≤t≤109)表示小数(含小数点)的长度以及四舍五入的次数。

第二行为一个字符串表示qdgg的初始分数。

输出描述:

一行表示qdgg能得到的最高分数(请勿输出尾零)
#include <stdio.h>
#define MAX 200000
int main()
{
	int a = 0,i = 0;//循环变量
	char buf[MAX] = {0};//
	int len = 0, time = 0;
	scanf("%d %d %s",&len,&time,buf);//数据的输入
	while (buf[a]!= '.')//从前往后扫描,直到出现小数点,这时候我们就得到了小数点的下标
	{
		if (buf[a++] =='\0')//表示的是如果是字符串结束表示符'\0',就表示没有小数点,是整数的成绩
			break;
	}
	for (i = a + 1; i < len; i++)//从小数点的后一位开始进行四舍五入的操作
	{
        //四舍五入是从某一位开始进位或者舍弃,但是后面的都变成了0,所以从前往后扫描
		if (buf[i] >= '5')//如果这一位大于等于5,就能进位了,但是进位后要看前面的数字的情况
		{
			buf[i--] = '\0';//这里表示这串数字在进位的这个数字处结束
			time--;//表示的是四舍五入的次数少一次
			while (buf[i] =='4'&&time--)//判断条件表示的是前一位数字是4且四舍五入的次数没有消耗完全的情况,这时候我们是丢弃这一位,然后退到前一位,再看前一位的情况(这里之所以是4,是因为只有4+1,才能在原来要舍去的情况下进位,使得成绩是最大值)
			{
				buf[i--] = '\0';
			}
			if (buf[i] == '.')//如果一直到了小数点后面都是4
			{
				buf[i--] = '\0';//表示这一位是小数点,就要停止四舍五入,同时将后面的数字全部赋值位0(包括小数点)
				time--;
                //来到了整数部分
				while (buf[i] == '9')
					buf[i--] = '0';//表示的是整数位上是9且要进位的时候
				if (i == -1)//表示最高位也要进位的时候
					putchar('1');//举个例子就是:999.99,进位就是1000,这个1是要自己补充上的
				else//如果不是,就要+1
					buf[i]++;//举个例子就是:989.99,进位就是990
				break;//跳出循环,是因为到了整数部分
			}
			else//如果1.位数四舍五入次数耗尽 或者2.不是4的时候:这一位+1
				buf[i]++;
		}
	}
	printf("%s", buf);//将后面的字符串都输出
	return 0;
}

总结:1.要想找到算法,首先得搞清楚如何四舍五入才能使得成绩最大。

           2.然后就是对于数字是4,5和9的分析,找到改进位还是舍去,还是要在最前面补1。

           3.最后就是对于最后后面的0的处理,对于字符串,我们直接在进位或者舍弃的那一位赋值位'\0',表示字符串结束即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值