20-21(2)第5次线上赛题解

为什么这次突然做题解了呢

因为这次的题目比较简单

哈哈哈哈哈(doge)


1:签到题-6

题意:

提供 m 个数字,有且仅有一个数字重复,找到该数字。

题解:

使用 set 容器(其实这里可以用 multiset)使用方法参考《[C++STL] set 容器的入门》或者网络/书本中的其他资源

上板子:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
    set<int>name;
    int n;
    cin >> n;
    while(n--)
    {
        int a;
        cin >> a;
        if (name.count(a))cout << a << endl;
        else name.insert(a);
    }
    return 0;
}

2:XCPC

题意:

根据提供字符串,判断出X、P、C的个数,判断能组成多少个 XCPC 或 CCPC,(不区分大小写)。

题解:

方法一:先排XCPC后排CCPC,模拟一遍。

方法二:根据XCPC和CCPC的数量关系,判断XCPC和CCPC的个数(找数学关系)。

上板子:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll pn, cn, in;
int main()
{
    ll T;
    cin >> T;
    string s;
    while (T--)
    {
        int num = 0;
        pn = 0, cn = 0, in = 0;
        cin >> s;
        for (ll i = 0;i < s.length();i++)
        {
            if (s[i] == 'p' || s[i] == 'P')pn++;
            else if (s[i] == 'c' || s[i] == 'C')cn++;
            else if (s[i] == 'i' || s[i] == 'I')in++;
            else continue;
        }
        while (in > 0)
        {
            in--;
            if (pn > 0 && cn > 1)
            {
                pn -= 1;
                cn -= 2;
            }
            else break;
            num++;
        }
        while (cn > 2)
        {
            cn -= 3;
            if (pn > 0) 
            {
                pn -= 1;
            }
            else break;
            num++;
        }
        cout << num << endl;
    }
    return 0;
}

3:取石子游戏

题意:

甲、乙、丙三人在玩取石子游戏,初始时甲有 A 个石子,乙有 B 个石子,丙有 C 个石子。

每个回合中,甲会从乙那里拿 a 个石子,乙会从丙那里拿 b 个石子,丙会从甲那里拿 c 个石子。

由于三个人总是同时行动,所以可能会出现这样一种情况:某个回合开始时,乙拥有的石子数量 x 不足 a 个,那么甲只能从乙那里拿 x 个石子,回合结束时,乙拥有的石子数量应该等于在本回合中从丙那里获取的石子数。

你需要计算在 n 个回合后,甲、乙、丙拥有的石子数量。

题解:

模拟每一次行动的结果,只需要判断剩余的石头数量是否大于将被取走的石头数量,避免出现负数就行。

这里我用了条件运算符来减少运算量。

关于 printf 和 scanf :

我学的还不是特别明白,这里就不做解释说明了

上板子:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        int n, a, b, c, A, B, C;
        cin >> n >> A >> B >> C >> a >> b >> c;
        int a1, b1, c1;
        while (n--)
        {
            c1 = (A > c ? c : A);
            a1 = (B > a ? a : B);
            b1 = (C > b ? b : C);
            A = A - c1 + a1;
            B = B - a1 + b1;
            C = C - b1 + c1;
        }
        printf("%d %d %d\n", A, B, C);
    }
    return 0;
}

 


4:中位数-2

题意:

有 n 个数字,有 m 次操作,操作只会是a:发出此时的中位数,b:加入一个数 x。

题解:

先读入 n 个数到 set 容器中,使用循环找到中位数,然后输出中位数或加入一个新的数。

上板子: 

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n, m, x;
    cin >> n >> m;
    multiset<int>t;
    for (int i = 0; i < n; i++)
    {
        cin >> x;//可以用 scanf("%d", &x),减少时间
        t.insert(x);
    }
    multiset<int>::iterator it = t.begin();
    for (int i = 1; ; ++it, ++i)
    {
        if (i == (t.size() + 1) / 2)break;//找到中间的那个数,如果为偶数,那就存较小的数
    }
    while (m--)
    {
        string s;
        cin >> s;
        if (s == "Query")
        {
            if (t.size() % 2 == 0) cout << (*it++ + *it--) / 2 << endl;
            else cout << *it << endl;
        }
        else if (s == "New")
        {
            cin >> x;
            t.insert(x);
            if (t.size() % 2 == 0)
            {
                if (x < *it)it--;
            }
            else if (x > *it)it++;
        }
    }
    return 0;
}

 


5:生成排列

题意:

现在给你 n 个数字,你每次可以将其中的任意一个数字进行加一或减一的操作,请问你至少需要操作多少次才能使其包含 1 ~ n 所有数字。

题解:

记得开long long!

上板子:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[100020];
int main()
{
    int T;
    cin >> T;
    while (T--)
    {
        ll ans = 0;
        int n;
        cin >> n;
        for (int i = 0;i < n;i++)
            cin >> a[i];
        sort(a, a + n);
        for (int i = 0;i < n;i++)
            ans += abs(a[i] - i - 1);
        cout << ans << endl;
    }
    return 0;
}

 

最后一道不会写

 

 

制作:BDT20040

祝大家学习进步,出题组早日秃头(bushi)

posted @ 2021-06-12 23:45  流白李  阅读(72)  评论(0编辑  收藏  举报