暑训日记Day3 T1《成绩》题解 (四舍五入、贪心)

T1 成绩

【问题描述】

Y Y Y参加完考试,获得了 x x x的成绩。现在他有 m m m次对 x x x进行四舍五入操作的机会,每次可以任意选一个位置进行四舍五入,请帮他最大化他的成绩。

【输入格式】

第一行两个数 n n n m m m,表示 x x x的长度为 n n n(包括小数点),与 m m m次机会。
第二行有一个实数 x x x,表示 Y Y Y的成绩。

【输出格式】

输出一行,表示答案。

【输入输出】

【输入样例1】

6 1
10.245

【输出样例1】

10.25

【输入样例2】

6 2
10.245

【输出样例2】

10.3

【输入样例3】

3 100
9.2

【输出样例3】

9.2

【数据范围】

对于前 40%的数据 n ≤ 10 n ≤ 10 n10
对于前 60%的数据 n ≤ 6666 n ≤ 6666 n6666
对于另外 5%的数据 m = 0 m = 0 m=0
对于 100%的数据 n ≤ 2 ∗ 1 0 5 , m ≤ n 。 n ≤ 2*10^5, m ≤ n。 n2105,mn
数据有一定梯度。

【题解】

由样例可知必须四舍五入小数点以后的数位,
继而贪心可知必须从大位向小位四舍五入,
所以只需 O ( m ) O(m) O(m)地扫一遍,遇到 < = 4 <=4 <=4的保留,遇到 > = 5 >=5 >=5的进位,
注意一些细节。
虽然基础,但是有些毒瘤,很可惜没拿满分。。说实话这道题很像高精加,但就是因为高精加忘光光了所以没打出来。。。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 200005; 
int n,m,flag,cot,cnt;//flag判小数点,cot存整数位数,cnt存小数位数 
int a[maxn],f[maxn];//a存整数位,f存小数位 
char ch; string s;
inline int Read(){//快读
  char c = getchar();
  int x = 0,f = 1;
  while(c < '0' || c > '9'){
    if(c == '-') f = -1;
    c = getchar();
  }
  while(c >= '0' && c <= '9'){
    x = x * 10 + c - '0';
    c = getchar();
  }
  return x * f;
}void Rite(int x){//快输
  if(x > 9)Rite(x / 10);
  putchar(x % 10 + '0');
}
int main() {
  freopen("grade.in", "r", stdin);
  freopen("grade.out", "w", stdout);
  n = Read(); m = Read();
  if(!m){ // 霸气特判 
	cin >> s;
	cout << s << endl;
	return 0;
  }
  flag = 0; cnt = 0; cot = 0;
  for(int i = 1;i <= n;++i){
	ch = getchar();
	if(ch == '.')
	  flag = 1;
	else{
	  if(!flag)
		++cot, a[cot] = ch - '0';
	  else{
		++cnt, f[cnt] = ch - '0';
		if(f[cnt] >= 5) break;//注意 
	  }
	}
  }
  while(f[cnt] >= 5 && m) {
	--m; ++f[cnt - 1];
	int i = cnt - 1;
	while (f[i] >= 10 && i) {
	  ++f[i - 1]; f[i] -= 10;
	  --i;//类似高精处理 
	}
    --cnt;
  }
  a[cot] += f[0];//处理前导 
  for(int i = cot;a[i] >= 10 && i;--i){
	a[i - 1] += a[i] / 10;
	a[i] = a[i] % 10;
  }
  if(a[0]) Rite(a[0]);
  for(int i = 1;i <= cot;++i)
	Rite(a[i]);
  if(cnt){
	putchar('.');
	for(int i = 1;i <= cnt;++i)
	  Rite(f[i]);
  }
  return 0;
}

看完请留下你的痕迹 t h x thx thx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值