【题解】
每次找小数位最靠左的且大于等于5的位置就可以了。
每次进完位可能新出现5.但是新出现的5肯定是进位后出现的。
看看那些进位后的数有哪个是5就记录一下。因为是从右往左进位。所以找到的肯定是最左边的5了。
这很顺利;
但是我竟然把有没有小数部分的条件改成小数第一位是不是0;
3.03有小数部分啊!!!!
然后我是把小数和整数部分倒过来做的。(做高精度的那种思想);
然后小数部分如果可以进位到整数部分,进的位就在小数部分的l+1的位置(因为是倒过来的);
所以最后正数部分加上小数部分[l+1];
然后在正数部分再进位。
最后再从整数开始逆序输出整数的数组;
根据小数部分的最后的位置判读有没有小数部分(-_-)!;
然后输出点号,逆序输出小数部分。
【代码】
#include <cstdio>
#include <cstring>
#include <cstdlib>
const int MAXN = 209000;
char s[MAXN];
int xiaoshu[MAXN], zhengshu[MAXN];
int len, l = 0, pos5 = 0, t, ma_x, pre, pos, ll = 0;
void input_data()
{
scanf("%d%d", &len, &t);
scanf("%s", s);
for (int i = len - 1; i >= 0; i--)
if (s[i] != '.')
{
l++;
xiaoshu[l] = s[i] - '0';
}
else
{
pos = i;
break;
}
for (int i = pos - 1; i >= 0; i--)
{
ll++;
zhengshu[ll] = s[i] - '0';
}
}
void output_ans()
{
for (int i = 1; i <= pre; i++)//把该置0的置0
xiaoshu[i] = 0;
zhengshu[1] += xiaoshu[l + 1];//加上进到整数的部分
for (int i = 1; i <= ll; i++)//正数部分再尝试进位
{
zhengshu[i + 1] += (zhengshu[i] / 10);
zhengshu[i] = zhengshu[i] % 10;
}
if (zhengshu[ll + 1] > 0)
ll++;
for (int i = ll; i >= 1; i--)
printf("%d", zhengshu[i]);
if (pre + 1 <= l)//不要写成xiaoshu[l]!=0 .....
{
printf(".");
for (int i = l; i >= pre + 1; i--)
printf("%d", xiaoshu[i]);
}
printf("\n");
}
//89.2343
//xioshu[1..l]={3,4,3,2}
//zhengshu[1..2] = {9,8};
void get_ans()
{
pre = 0;
ma_x = 1;
for (int i = l; i >= 1; i--)
if (xiaoshu[i] >= 5)
{
pos5 = i;
break;
}
if (pos5 == 0)//如果没有能让结果更大的情况出现就结束
{
printf("%s\n", s);
exit(0);
}
pre = pos5;//pre表示1..pre都置0
while (t)
{
xiaoshu[pos5 + 1]++;
int tempj = pos5 + 1;
int x = xiaoshu[tempj] / 10;
xiaoshu[tempj] %= 10;
pos5 = 0;
if (xiaoshu[tempj] >= 5)//只有进位之后才可能出现新的5
pos5 = tempj;
while (x)//进位
{
tempj++;
xiaoshu[tempj] += x;
x = xiaoshu[tempj] / 10;
xiaoshu[tempj] %= 10;
if (xiaoshu[tempj] >= 5)//最靠近左边的5
pos5 = tempj;
}
t--;
if (pos5 == 0)//如果没有新的5了就退出
{
output_ans();
exit(0);
}
else
{
if (t)
pre = pos5;
}
}
output_ans();
}
int main()
{
//freopen("F:\\rush.txt", "r", stdin);
input_data();
get_ans();
return 0;
}