欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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',如果在小数点前面进位直接循环处理即可,这样处理起来不容易错。