CF718A Efim and Strange Grade 題解
演算法
貪心+模擬
思路分析
顯然,要最優每一次進位就只能五入不能四舍。而且當我們五入時,要取位數最高的。比如說 \(1.3535\),我們有兩種進位方式,一種是進位成 \(1.4\),一種是進位成 \(1.354\),顯然前者更優。
那這道題給的次數有啥用呢?
考慮一種“連環進位”。舉個例子,\(2.4445\) 最終結果應該是 \(2.5\),進位三次。那我們的程式碼就很好設計了,先找到位數最高的大於五的數位,然後再向前找連續的 \(4\),連續的個數就是我們達到最優的次數,判斷一下和所給的 \(t\) 的大小關係即可。
注意進位時 \(9\) 的再次進位,以及整數位進位會超 long long
等細節問題。
程式碼
程式碼僅供參考
#include <bits/stdc++.h>
using namespace std;
namespace Raiden
{
int a = -1, b;
signed work()
{
string s, s1;
int n, t;
cin >> n >> t;
cin >> s;
int st = s.find(".");
for (int i = st + 1; i < s.size(); i++)
{
if (s[i] - '0' >= 5)
{
a = i;
break;
}
}
for (int i = a - 1; i >= st; i--)
{
if (s[i] - '0' == 4)
b++;
else
break;
}
if (a == -1)
cout << s << endl;
else if (a == st + 1)
{
string s1 = s.substr(0, st);
for (int i = st-1; i >= 0; i--)
{
if (s1[i] != '9')
{
s1[i]++;
break;
}
else
s1[i] = '0';
}
if (s1[0] == '0')
cout << 1 << s1 << endl;
else
cout << s1 << endl;
}
else if (t >= b + 1)
{
if (a - b == st + 1)
{
string s1 = s.substr(0, st);
for (int i = st-1; i >= 0; i--)
{
if (s1[i] != '9')
{
s1[i]++;
break;
}
else
s1[i] = '0';
}
if (s1[0] == '0')
cout << 1 << s1 << endl;
else
cout << s1 << endl;
}
else
{
if (s[a - b - 1] == '9')
cout << s.substr(0, a - b - 2) << char(s[a - b - 2] + 1) << '0' << endl;
else
cout << s.substr(0, a - b - 1) << char(s[a - b - 1] + 1) << endl;
}
}
else
{
if (s[a - t] == '9')
cout << s.substr(0, a - t - 1) << char(s[a - t - 1] + 1) << '0' << endl;
else
cout << s.substr(0, a - t) << char(s[a - t] + 1) << endl;
}
return 0;
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
return Raiden::work();
}