补题:Codeforces 954(Div3)A-D

A题

题意:在X轴上找出一点,使其到三个点的距离最短;

题解:其实不难发现,最短距离就是三个点的最大值减去最小值

AC代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int _;
    cin >> _;
    while(_--)
    {
        array<int,3>a;
        for (int i = 0; i < 3;++i)
            cin >> a[i];
        sort(a.begin(), a.end());
        cout << a[2] - a[0] << '\n';
    }
}

B题

题意:题目给你一个n×m的矩阵,并给明一种操作:如果当前的Aij大于周围的所有元素,则Aij-1;不难发现,这种减一操作会一直持续到他和相邻元素中的最大值相等为止,且题目要求有多个这种需要减一元素时,先对i较小的进行操作,如果i一样,就对j较小的进行操作

题解:观察题目数据范围,n,m的范围都是100以内,所以可以直接暴力求解,遍历整个数组,一旦比周边大就将该数据改为邻边元素最大的哪一个

AC代码

using namespace std;
void solve()
{
    int n, m;
    cin >> n >> m;
    vector<vector<int>> a(n+2,vector<int>(m+2));//vector初始化二维数组,多开两个是为了防止越界
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= m; ++j)
            cin >> a[i][j];
    }
    for (int i = 0; i <= n; i++)
    {
        for (int j = 0; j <= m; ++j)
        {
            if (a[i][j] > a[i + 1][j] && a[i][j] > a[i][j + 1]&&a[i][j]>a[i-1][j]&&a[i][j]>a[i][j-1])
            {
                a[i][j] = max(max(a[i][j + 1], a[i + 1][j]),max(a[i-1][j],a[i][j-1]));
            }
        }
    }
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= m;++j)
            cout << a[i][j] << ' ';
        cout << '\n';
    }
}
int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int _;
    cin >> _;
    while (_--)
        solve();
}

C题

题意:给你一个字符串a,a是待操作的字符串.然后给你一个数组b和一串字符串s,你需要按照数组和s对a进行更改,即a[b[i]]=s[i];现在你可以对数组b和字符串s进行你想要的排列,使最后得到的a的字典序排列最大(即在第一个和原字符串不同字母的地方能有a'[i]>a[i],a'[i]是更改后的字符串)

题解:不难发现,我们肯定第一步是要对s进行排列的,让s中字典序大的尽量多的更换到a中去,我们也可以发现,如果b中出现两个相同的数字,比如出现两个2,那么最后a[2]会采用第二个2对应的s[i],所以,我们可以贪心的想,我们把b排序去重后,使其与排序后的s一一对齐,就可以使a替换后的字符串最大,至于b中被去重的那一部分数字对应的s[i]是多少,我们并不关心,我们只要保证最后的b对应的s[i]是最优的即可.

AC代码

#include <bits/stdc++.h>
using namespace std;
void solve()
{
    int n, m;
    cin >> n >> m;
    string s;
    cin >> s;
    vector<int> a(m);
    map<int, char> mp;
    for (int i = 0; i < m; ++i)
    {
        cin >> a[i];
    }
    string b;
    cin >> b;
    sort(a.begin(), a.end());
    a.erase(unique(a.begin(), a.end()), a.end());//排序去重的模板
    sort(b.begin(), b.end());
    for (int i = 0,w=0; i < a.size(); ++i,++w)
    {
        mp[a[i]] = b[w];用map建立一一映射关系

    }
    for (auto [x, y] : mp)
    {
        s[x - 1] = y;//因为数组a中给的是顺序,我们要求的是下标,故要-1
    }
    cout << s << '\n';
}
int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int _;
    cin >> _;
    while (_--)
        solve();
}

D题(有没有佬能教我dp(悲))

题意:给你一个长度为n的字符串(由0-9组成),你需要在其中加入n-2个'+'或者'×',使其最后的运算结果最小

题解:我们不难发现,如果给出的字符串中存在0,我们只需使0×其他数即可保证最后结果是0,即最小值,如果字符串中有1,我们用乘法可以直接跳过这个1,因为他对结果起不了改变.

又因为我们有n个数,但只有n-2个符号,所以肯定是会留下一个两位数的,我们可以暴力枚举出这个两位数的情况,最后得出最小值即可

AC代码

#include <bits/stdc++.h>
using namespace std;
void solve()
{
    int n;
    cin >> n;
    string s;
    cin >> s;
    vector<int> a(n);
    for (int i = 0; i < n; ++i)
        a[i] = s[i] - '0';
    int ans = 101010;
    for (int i = 1; i < n; i++)
    {
        vector<int> pack;//用来打包每个数
        for (int j = 0; j < n; j++)
        {
            if (j == i - 1)
            {
                int x = a[j] * 10 + a[j + 1];//枚举的两位数
                pack.push_back(x);
                j++;
            }
            else
                pack.push_back(a[j]);
        }
        int res = 0;
        for (auto w : pack)
        {
            if (w == 0)
            {
                cout << 0 << '\n';
                return;
            }
            else if (w == 1)
                continue;//乘法可直接跳过,不会有影响
            else
                res += w;
        }
        if (res == 0)
            res++;//res为0的情况只有可能是全为1都被continue掉了,这个时候我们要手动+1为最终结果
        ans = min(ans, res);
    }
    cout << ans << '\n';
}
int main()
{
    int _;
    cin >> _;
    while (_--)
        solve();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值