Codeforces Round 1017 (Div. 4) (A~E)

Problem A

A. Trippi Troppi

题面:

特里皮·特罗皮生活在一个奇怪的世界。每个国家的古名都由三串字组成。每个字符串的第一个字母被连接起来,形成这个国家的现代名称。

给定国家的古代名称,请输出现代名称。

题解:

输出三个字符串的首字符即可

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned;
using u128 = unsigned __int128;
void solve()
{
    string s;
    for (int i = 0; i < 3;i++){
        cin >> s;
        cout << s[0];
    }
    cout << endl;
}
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

Problem B

B. Bobritto Bandito

题面:

在波布里托-班迪托居住的小镇上,在一条无穷数线上有无数的房子,房子的位置是 … , − 2 , − 1 , 0 , 1 , 2 , … \ldots, -2, -1, 0, 1, 2, \ldots ,2,1,0,1,2, 。在第 0 0 0 天,他让房子 0 0 0 的不幸居民感染了瘟疫。接下来的每一天,瘟疫都会传播到***个健康的家庭,而这些家庭都紧挨着一个受感染的家庭。可以看出,每天受感染的房屋形成一个连续的片段。

假设从 l l l (第3户)开始到 r r r (第3户)结束的这一段被记为 [ l , r ] [l, r] [l,r] 。你知道在 n n n 天后, [ l , r ] [l, r] [l,r] 段受到感染。请找出可能在第 m m m 天( m ≤ n m \le n mn )被感染的线段 [ l ′ , r ′ ] [l', r'] [l,r]

题解:

创建两个边界,在没有到达左边界以及没有到第m天的情况下,向左移动左边界,如还有天数剩余,向右移动右边界

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned;
using u128 = unsigned __int128;
void solve()
{
    int n, m, l, r;
    cin >> n >> m >> l >> r;
    int l1 = 0, r1 = 0;
    for(int i=0;i<m;i++){
        if(l1>l){
            l1--;
        }else {
            r1++;
        }
    }
    cout << l1 << " " << r1 << endl;
}
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

Problem C

C. Brr Brrr Patapim

题面:

Brr Brr Patapim 正试图知道 Tiramisù 的秘密密码,那是 2 ⋅ n 2\cdot n 2n 个元素的排列组合 ∗ ^{\text{∗}} 。为了帮助帕塔皮姆猜测,提拉米苏给了他一个 n × n n\times n n×n 网格 G G G ,其中 G i , j G_{i,j} Gi,j (或者说网格中 i i i /th行和 j j j /th列中的元素)包含 p i + j p_{i+j} pi+j ,或者说排列中的 ( i + j ) (i+j) (i+j) /th元素。

给定这个网格,请帮助帕塔皮姆破解被遗忘的密码。可以保证这个排列是存在的,而且可以证明这个排列是唯一确定的。

∗ ^{\text{∗}} m m m 个整数的排列是 m m m 个整数的序列,其中每个整数都恰好包含 1 , 2 , … , m 1,2,\ldots,m 1,2,,m 次。例如, [ 1 , 3 , 2 ] [1, 3, 2] [1,3,2] [ 2 , 1 ] [2, 1] [2,1] 是排列,而 [ 1 , 2 , 4 ] [1, 2, 4] [1,2,4] [ 1 , 3 , 2 , 3 ] [1, 3, 2, 3] [1,3,2,3] 不是排列。

题解:

我们观察到对于n阶的行列式,副对角线的元素相同,因此只需要输出网格的第一行和最后一列,并在这之前输出MEX

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned;
using u128 = unsigned __int128;
void solve()
{
    int n;
    cin >> n;
    vector<vector<int>> num(n, vector<int>(n));
    vector<int> seen(n * 2 + 1, 0);
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            int a;
            cin >> a;
            num[i][j] = a;
            seen[a]++;
        }
    }

    for (int i = 1; i <= n * 2; i++)
    {
        if (seen[i] == 0)
        {
            cout << i << " ";
            break;
        }
    }
    for (int j = 0; j < n; j++)
    {
        cout << num[0][j] << " ";
    }
    for (int i = 1; i < n - 1; i++)
    {
        cout << num[i][n - 1] << " ";
    }
    if (n != 1)
        cout << num[n - 1][n - 1] << endl;
    else
        cout << endl;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

Problem D

D. Tung Tung Sahur

题面:

你面前有两面鼓:一面是左鼓,一面是右鼓。敲击左边的鼓可以记录为 “L”,敲击右边的鼓可以记录为 “R”。

统治这个世界的奇异力量是善变的:有时敲击一次,有时敲击两次。因此,敲击左边鼓的声音可能是 "L "或 “LL”,敲击右边鼓的声音可能是 "R "或 “RR”。

击鼓的顺序记录在字符串 p p p 中,听到的声音记录在字符串 s s s 中。给定 p p p s s s ,判断字符串 s s s 是否可能是字符串 p p p 敲击的结果。

例如,如果 p = p= p= “LR”,那么点击的结果可能是 “LR”、“LRR”、"LLR "和 "LLRR "中的任何一个,但字符串 "LLLR "或 "LRL "则不可能。

题解:

从头遍历两个字符串,记录相同元素个数cntp,cnts,每到第一个不同的元素,就先进行判断。如果 c n t s < c n t p cnts<cntp cnts<cntp或者 c n t s > c n t p × 2 cnts > cntp\times2 cnts>cntp×2,则不可能,
若满足条件则继续遍历判断,直到一个字符串遍历结束。此时如果其中一个字符串的索引没有完全遍历字符串,则不可能

AC代码:

#include <bits/stdc++.h>
using namespace std;

void solve()
{
    string p, s;
    cin >> p >> s;
    int i = 0, j = 0;
    while (i < p.size() && j < s.size())
    {
        if (p[i] != s[j])
        {
            cout << "NO\n";
            return;
        }

        int cntp = 0;
        char ch = p[i];
        while (i < p.size() && p[i] == ch)
        {
            cntp++;
            i++;
        }
        int cnts = 0;
        while (j < s.size() && s[j] == ch)
        {
            cnts++;
            j++;
        }

        if (cnts < cntp || cnts > cntp * 2)
        {
            cout << "NO\n";
            return;
        }
    }

    if (i == p.size() && j == s.size())
    {
        cout << "YES\n";
    }
    else
    {
        cout << "NO\n";
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

Problem E

E. Boneca Ambalabu

题面:

博尼卡-安巴拉布给你一个由 n n n 个整数 a 1 , a 2 , … , a n a_1,a_2,\ldots,a_n a1,a2,,an 组成的序列。

请输出所有 1 ≤ k ≤ n 1 \leq k \leq n 1kn ( a k ⊕ a 1 ) + ( a k ⊕ a 2 ) + … + ( a k ⊕ a n ) (a_k\oplus a_1)+(a_k\oplus a_2)+\ldots+(a_k\oplus a_n) (aka1)+(aka2)++(akan) 的最大值。注意 ⊕ \oplus 表示 bitwise XOR 运算

题解:

对于每一位,从高到低遍历,记录每一位上 1 的数量。然后对于数组中每个元素 ak,我们逐位判断它是否是 1,如果是:它这一位对异或结果有贡献的是0 的数量。如果它是 0,则贡献的是1 的数量。所以我们可以计算每个ak的异或和

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned;
using u128 = unsigned __int128;
void solve()
{
    int n;
    cin >> n;
    vector<int> a(n);
    for (auto &x : a)
        cin >> x;
    const int bit = 30;
    vector<int> cnt1(bit, 0);
    for (int x : a)
    {
        for (int b = 0; b < bit; b++)
        {
            if (x & (1 << b))
                cnt1[b]++;
        }
    }
    i64 ans = 0;
    for (int i = 0; i < n; ++i)
    {
        i64 sum = 0;
        for (int b = 0; b < bit; ++b)
        {
            if (a[i] & (1 << b))
            {
                sum += 1LL * (n - cnt1[b]) * (1 << b);
            }
            else
            {
                sum += 1LL * cnt1[b] * (1 << b);
            }
        }
        ans = max(ans, sum);
    }
    cout << ans << '\n';
}
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值