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
n≤10 ,
对于前 60%的数据
n
≤
6666
n ≤ 6666
n≤6666 ,
对于另外 5%的数据
m
=
0
m = 0
m=0 ,
对于 100%的数据
n
≤
2
∗
1
0
5
,
m
≤
n
。
n ≤ 2*10^5, m ≤ n。
n≤2∗105,m≤n。
数据有一定梯度。
【题解】
由样例可知必须四舍五入小数点以后的数位,
继而贪心可知必须从大位向小位四舍五入,
所以只需
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