Codeforces Round 891 (Div. 3)

比赛链接

完成度:4/7

这场比赛相对于上次那场909 div3,题目描述清楚许多(可能是出简单了)。


首先是B题,一道模拟四舍五入的题目

题目B

这题就是简单模拟,我们需要读入一个数字字符串,把他输入到一个数组当中,然后从低位到高位找大于等于5的数,如果找到了,那么之前的数包括这个数都变成0,下一位加一,这里有个特判,如果这个数是最后一个数,那就把这个数换成10,相当于向上进一位。在操作完成之后输出结果数组即可

#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <map>
#include <string>
#define int long long
using namespace std;

const int N = 200010;

void solve()
{
    string s;
    cin >> s;
    int len = s.size();
    vector<int> a(len, 0);
    for (int i = len - 1; i >= 0; i--)//处理字符串
    {
        a[i] = s[len - 1 - i] - '0';
    }
    bool check = false;
    int k = 0, j = 0, mark = -1;
    while (k < len) //处理完就停下
    {
        while (a[j] < 5 && j < len)//找大于等于5的数
        {
            j++;
        }
        k = j;
        if (a[j] >= 5 && j < len)
        {
            if (k < len - 1)
            {
                a[k + 1]++;
                mark = k; //在mark之前的数输出的时候都只输出个0
                k++, j++;
            }
            else if(k == len - 1)//特判
            {
                a[k] = 10;
                mark = k - 1;
                k++, j++;
            }
        }
    }
    for (int i = len - 1; i >= 0; i--) //输出
    {
        if (i <= mark) //mark之前的数
        {
            cout << 0;
        }
        else
        {
            cout << a[i];
        }
    }
    cout << endl;
}

signed main()
{

    int tNum;
    cin >> tNum;
    for (int i = 0; i < tNum; i++)
    {
        solve();
    }

    return 0;
}

题目C

题目C需要用到贪心与一些数学知识,这题让我们还原原数组,我们可以这样想,假如原数组里面有一个最小的数,那么不管这个数在数组里面的位置如何,处理过后的数组中这个数的出现次数是不变的,可以自己写几个数组模拟试试,那么这样就好办了,我们只用给题目给的操作后的数组排个序,然后从小到大按出现个数来把数字添加到答案数组(最小的第一个数出现的次数是n-1,第二个是n-2,以此类推),最后一个数也就是原数组里面最大的那个数不会出现在操作后得到的数组中,我们随便选一个就行,但是要注意最好是等于倒数第二大的那个数,直接把倒数第二大的那个数加一会超出数据范围(别问是咋知道的,说出来都是泪)

#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <map>
#include <string>
#define int long long
using namespace std;

const int N = 200010;

void solve()
{
    int n;
    cin >> n;
    vector<int> a((n * (n - 1)) / 2, 0);
    vector<int> b;
    for (int i = 0; i < (n * (n - 1)) / 2; i++) //输入操作后的数组
    {
        cin >> a[i];
    }

    sort(a.begin(), a.end()); //排序
    int mark = 0;
    n--; //因为最后大的数我们不知道所以填数的时候要减去这个数,在填完之后我们再选一个加进去
    while (n)
    {
        b.push_back(a[mark]);
        cout << a[mark]<<" ";
        mark += n;
        n--;
    }
    cout << a.back() << endl; //这里就是直接等于倒数第二大的那个数
}

signed main()
{

    int tNum;
    cin >> tNum;
    for (int i = 0; i < tNum; i++)
    {
        solve();
    }

    return 0;
}


最后是D题这题还是用到了点数学知识和贪心

题目D

他给了我们一个公式,根据这个公式找到强顶点,先从这个公式下手,可以化简成 au−bu≥av−bv,也就是输入第一个数组元素减去输入第二个数组对应的元素里面最大的那几个数就是强顶点,然后循环减去后的数组找答案就行

#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <map>
#include <string>
#define int long long
using namespace std;

const int N = 200010;

void solve()
{
    int n, x;
    cin >> n;
    vector<int> a(n + 1, 0);
    vector<int> b;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
    }
    int maxx = -20000000000, ans = 0;//maxx要注意数据范围不能是-1,题目数据给的最小值是-10^9
    for (int i = 1; i <= n; i++)
    {
        cin >> x;
        a[i] -= x;
        if (a[i] > maxx) //标记最大值
        {
            maxx = a[i];
        }
    }

    for (int i = 1; i <= n; i++)
    {
        if (a[i] == maxx)
        {
            ans++;
            b.push_back(i);//把数的编号填入答案数组
        }
    }
    cout << ans << endl;
    for (int i = 0; i < b.size(); i++)
    {
        cout << b[i] << " ";
    }
    cout << endl;
}

signed main()
{

    int tNum;
    cin >> tNum;
    for (int i = 0; i < tNum; i++)
    {
        solve();
    }

    return 0;
}
posted @   chhh31  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示