【题解】
每次找小数位最靠左的且大于等于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(" "); } //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 ", 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; }