0%

Codeforces 719C - Efim and Strange Grade (模拟

题目链接:
http://codeforces.com/problemset/problem/719/C

题目大意:
小明现在得知了自己的考试成绩是一个算上小数点共n位的小数,一共有t秒时间,每秒小明都可以对自己的小数点后的成绩进行一次四舍五入,问小明最大的成绩是多少

分析:
先找到小数点位置,因为四舍五入必须从小数点后进行,然后选择最靠近小数点的一位进位,如此t次,无法进位时退出,但此做法会超时,因为每次重新找要四舍五入的下标再进行进位会消耗很多时间,所以可以在进位的同时加上判断

  1. 进位后当前位>9,进位到下一位
  2. 进位后当前位>4,如果还有时间,直接在此处继续四舍五入
  3. 进位后当前位<=4,成绩已无法再进位,输出结果

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

int n , t ,length;
char str[200009];
char ans[200009];

bool change(int pos)
{
int cpos = -1;
for (int i = pos ; i < length ; i ++)
{
if (str[i]>='5')
{
cpos = i-1;
str[i] = '\0'; //截断后面的小数部分
length = i;
break;
}
}
int add = 1;
if (cpos !=-1) //如果有可四舍五入的地方
{
for (int i = cpos ; i >= 0 ; --i)
{
if (str[i]=='.')
continue;
str[i] = str[i] + add ;
if (str[i]>'9') //大于9,直接进位
{
str[i] = '0';
continue;
}
else if (str[i]>='5'&&t>0&&i>pos) //大于等于5且剩余进位次数不为0,且[当前位置在小数范围内]
{
--t;
str[i] = '\0';
length = i;
continue;
}
else
{
add = 0;
break;
}
}
if (str[length-1]=='.')
{
str[length-1] = '\0';
length -= 1;
}
if (add)
{
memcpy(ans+1,str,length);
ans[0] = '1';
length += 1;
memcpy(str,ans,length); //可能最高位在进位后>9,需要再前面再添1,由于这种情况只可能发生一次,所以两次memcpy也无妨
}
return true;
}
else
return false;
}

int searchpoint() //找到小数点所在位置
{
for (int i = 0 ; i < length ; i ++)
if (str[i]=='.')
return i+1;

}
int main()
{
scanf("%d%d",&n,&t);
scanf("%s",str);
length = strlen(str);
int pos = searchpoint();
while (--t>=0)
{
if (!change(pos))
break;
}
cout<<str<<endl;
return 0;
}