Codeforces 718A Efim and Strange Grade 程序分析
程序员文章站
2022-06-15 13:32:18
Codeforces 718A Efim and Strange Grade 程序分析 "jerry" 的程序 cpp using namespace std; typedef long long ll; string buf; int i; void up(int at) { at ; if (a ......
codeforces 718a efim and strange grade 程序分析
的程序
using namespace std; typedef long long ll; string buf; int i; void up(int at) { at--; if (at < 0) { buf = '1' + buf; i++; return; } if (buf[at] == '.') at--; buf[at]++; if (buf[at] == '9'+1) { buf[at] = '0'; up(at); } } int main() { cin.sync_with_stdio(false); cin.tie(0); int n, k; cin >> n >> k >> buf; while (buf[i] != '.') i++; i++; while (i < buf.length() && buf[i] <= '4') i++; if (i == buf.length()) { cout << buf << endl; return 0; } for (;buf[i] != '.' && k;i--) if (buf[i] >= '5') { buf.resize(i); up(i); k--; } if (buf.back() == '.') buf.pop_back(); cout << buf << endl; return 0; }
首先,先找到小数点第一个后大于等于5的数位,如果没有的话直接输出原数。
从那个数位起,从后往前循环到小数点处,如果还当前数位大于等于5且有进位的机会,则先把这个数的结尾改成这个位置,因为之后的所有数都会被清零,然后调用up函数进位,如果有9的数继续递归,否则退出,如果整数部分首位还要进位,需要在最前面加上1。
最后注意最后一个字符如果是小数点要删去。
总结:用一个函数来执行进位,如果还有进位机会只需继续调用函数就行了,这样处理起来十分方便。
的程序
#include <bits/stdc++.h> #define fo(i,a,b) for (int i = (a); i < (b); i++) #define sz(v) int(v.size()) using namespace std; char s[200005]; int main() { int l, t; scanf("%d %d", &l, &t); scanf("%s", s+1); s[0] = '0'; for (int i = 0; i <= l; i++) { if (s[i] == '.') { for (int j = i+1; j <= l; j++) if (s[j] >= '5') { s[j] = 0; bool roundup = true; t--; for (int k = j-1; k > i; k--) { // s[k]++ if (roundup) { s[k]++; if (s[k] >= '5' && t) { s[k] = 0; t--; roundup = true; } else roundup = false; } } if (roundup) { s[i] = 0; for (int k = i-1; k >= 0; k--) { s[k]++; if (s[k] <= '9') break; else s[k] = '0'; } } break; } } } if (s[0] != '0') { printf("%s\n", s); } else { printf("%s\n", s+1); } }
这个程序读入时在数字前加上一个前导零,以便处理整数部分首位进位情况。
第一层循环找到小数点的位置,第二层循环找到小数点后第一位大于等于5的数字,第三层循环(最多进位到小数点),roundup记录是否继续进位,如果进位后还有大于等于5的数字且还有进位机会,则继续进位。如果第三层循环结束后,仍需继续进位,则在整数部分进位。进位时每进位一次,就把这一位设置为’\0’,这样输出时只会输出到第一个’\0’的位置便结束。
注意最后需判断如果开始时加上的前导零仍是零,就不能输出。
总结:用bool变量roundup维护需不需要继续进位,进了位的位置就标为'\0',如果在小数点前面进位直接循环处理即可,这样处理起来不容易错。