Toyota Programming Contest 2024#3(AtCoder Beginner Contest 344)题解(c/c++)(A~E)

在这里插入图片描述

A - Spoiler

Problem Statement

You are given a string S S S consisting of lowercase English letters and |. S S S is guaranteed to contain exactly two |s.

Remove the characters between the two |s, including the |s themselves, and print the resulting string.

Constraints

  • S S S is a string of length between 2 2 2 and 100 100 100, inclusive, consisting of lowercase English letters and |.
  • S S S contains exactly two |s.

Sample Input 1

atcoder|beginner|contest

Sample Output 1

atcodercontest

Remove all the characters between the two |s and print the result.

思路: 非常简单的一道题,找出两个‘|’的位置即可,在输出时跳过

Code

#include <bits/stdc++.h>
#define ll long long
#define int long long
#define pii pair<int, int>
#define pb push_back
#define gcd __gcd
#define lcm(a, b) (a * b) / gcd(a, b)
#define all(a) a.begin(), a.end()
#define mem(a, x) memset(a, x, sizeof(a))
#define f(i, s, e) for (int i = s; i <= e; i++)
#define ff(i, s, e) for (int i = s; i >= e; i--)
#define setbits(x) __builtin_popcount(x)
#define zrobits(x) __builtin_ctzll(x)
#define mod 100000007
#define maxn (ll)(2e5 + 5000)
#define INF 0x3f3f3f3f
using namespace std;
// set<int>::iterator it;
void solve()
{
    string s;
    cin >> s;
    int n = s.size();
    int l = 0, r = 0;
    f(i, 0, n - 1)
    {
        if (s[i] == '|')
        {
            l = i;
            break;
        }
    }
    ff(i, n - 1, 0)
    {
        if (s[i] == '|')
        {
            r = i;
            break;
        }
    }
    f(i, 0, l-1)
    {
        cout << s[i];
    }
    f(i, r+1, n-1)
    {
        cout << s[i];
    }
    cout << endl;
    return;
}
signed main(void)
{
    ios::sync_with_stdio(false), cin.tie(nullptr);
    solve();
    return 0;
}

B - Delimiter

Problem Statement

You are given N N N integers A 1 , A 2 , … , A N A_1,A_2,\dots,A_N A1,A2,,AN, one per line, over N N N lines. However, N N N is not given in the input.
Furthermore, the following is guaranteed:

  • A i ≠ 0 A_i \neq 0 Ai=0 ( 1 ≤ i ≤ N − 1 1 \le i \le N-1 1iN1 )
  • A N = 0 A_N = 0 AN=0

Print A N , A N − 1 , … , A 1 A_N, A_{N-1},\dots,A_1 AN,AN1,,A1 in this order.

Constraints

  • All input values are integers.
  • 1 ≤ N ≤ 100 1 \le N \le 100 1N100
  • 1 ≤ A i ≤ 1 0 9 1 \le A_i \le 10^9 1Ai109 ( 1 ≤ i ≤ N − 1 1 \le i \le N-1 1iN1 )
  • A N = 0 A_N = 0 AN=0

Sample Input 1

3
2
1
0

Sample Output 1

0
1
2
3

Note again that N N N is not given in the input. Here, N = 4 N=4 N=4 and A = ( 3 , 2 , 1 , 0 ) A=(3,2,1,0) A=(3,2,1,0).

思路:简单题

Code

#include <bits/stdc++.h>
#define ll long long
#define int long long
#define pii pair<int, int>
#define pb push_back
#define gcd __gcd
#define lcm(a, b) (a * b) / gcd(a, b)
#define all(a) a.begin(), a.end()
#define mem(a, x) memset(a, x, sizeof(a))
#define f(i, s, e) for (int i = s; i <= e; i++)
#define ff(i, s, e) for (int i = s; i >= e; i--)
#define setbits(x) __builtin_popcount(x)
#define zrobits(x) __builtin_ctzll(x)
#define mod 100000007
#define maxn (ll)(2e5 + 5000)
#define INF 0x3f3f3f3f
using namespace std;
// set<int>::iterator it;
int a[maxn] = {0};
signed main(void)
{
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int w = 0;
    while (1)
    {
        int x;
        cin >> x;
        if (x == 0)
        {
            a[++w] = 0;
            break;
        }
        a[++w] = x;
    }
    ff(i, w, 1)
    {
        cout << a[i] << endl;
    }

    return 0;
}

C - A+B+C

Problem Statement

You are given three sequences A = ( A 1 , … , A N ) A=(A_1,\ldots,A_N) A=(A1,,AN), B = ( B 1 , … , B M ) B=(B_1,\ldots,B_M) B=(B1,,BM), and C = ( C 1 , … , C L ) C=(C_1,\ldots,C_L) C=(C1,,CL).

Additionally, a sequence X = ( X 1 , … , X Q ) X=(X_1,\ldots,X_Q) X=(X1,,XQ) is given. For each i = 1 , … , Q i=1,\ldots,Q i=1,,Q, solve the following problem:

Problem: Is it possible to select one element from each of A A A, B B B, and C C C so that their sum is X i X_i Xi?

Constraints

  • 1 ≤ N , M , L ≤ 100 1 \leq N,M,L \leq 100 1N,M,L100
  • 0 ≤ A i , B i , C i ≤ 1 0 8 0 \leq A_i, B_i ,C_i \leq 10^8 0Ai,Bi,Ci108
  • 1 ≤ Q ≤ 2 × 1 0 5 1 \leq Q \leq 2\times 10^5 1Q2×105
  • 0 ≤ X i ≤ 3 × 1 0 8 0 \leq X_i \leq 3\times 10^8 0Xi3×108
  • All input values are integers.

Sample Input 1

3
1 2 3
2
2 4
6
1 2 4 8 16 32
4
1 5 10 50

Sample Output 1

No
Yes
Yes
No
  • It is impossible to select one element from each of A A A, B B B, and C C C so that their sum is 1 1 1.
  • Selecting 1 1 1, 2 2 2, and 2 2 2 from A A A, B B B, and C C C, respectively, makes the sum 5 5 5.
  • Selecting 2 2 2, 4 4 4, and 4 4 4 from A A A, B B B, and C C C, respectively, makes the sum 10 10 10.
  • It is impossible to select one element from each of A A A, B B B, and C C C so that their sum is 50 50 50.

思路:暴力模拟即可

Code

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

int main()
{
    vector<int> A, B, C, X; 
    unordered_set<int> sums;
    int n;
    cin>>n;
    for (int i = 0; i < n; i++)
    {
        int a;
        cin >> a;
        A.push_back(a);
    }
    int m;
    cin>>m;
    for (int i = 0; i < m; i++)
    {
        int b;
        cin >> b;
        B.push_back(b);
    }
    int l;
    cin>>l;
    for (int i = 0; i < l; i++)
    {
        int c;
        cin >> c;
        C.push_back(c);
    }
    int p;
    cin>>p;
    for (int i = 0; i < p; i++)
    {
        int x;
        cin >> x;
        X.push_back(x);
    }
    for (int a : A)
    {
        for (int b : B)
        {
            sums.insert(a + b);
        }
    }
    for (int x : X)
    {
        bool found = false;
        for (int c : C)
        {
            if (sums.count(x - c))
            {
                found = true;
                break;
            }
        }
        cout << (found ? "Yes" : "No") << endl;
    }

    return 0;
}

D - String Bags

Problem Statement

You initially have an empty string S S S.
Additionally, there are bags 1 , 2 , … , N 1, 2, \dots, N 1,2,,N, each containing some strings.
Bag i i i contains A i A_i Ai strings S i , 1 , S i , 2 , … , S i , A i S_{i,1}, S_{i,2}, \dots, S_{i,A_i} Si,1,Si,2,,Si,Ai.

You will repeat the following steps for i = 1 , 2 , … , N i = 1, 2, \dots, N i=1,2,,N:

  • Choose and perform one of the following two actions:
    • Pay 1 1 1 yen, select exactly one string from bag i i i, and concatenate it to the end of S S S.
    • Do nothing.

Given a string T T T, find the minimum amount of money required to make the final S S S equal T T T.
If there is no way to make the final S S S equal T T T, print -1.

Constraints

  • T T T is a string consisting of lowercase English letters with length between 1 1 1 and 100 100 100, inclusive.
  • N N N is an integer between 1 1 1 and 100 100 100, inclusive.
  • A i A_i Ai is an integer between 1 1 1 and 10 10 10, inclusive.
  • S i , j S_{i,j} Si,j is a string consisting of lowercase English letters with length between 1 1 1 and 10 10 10, inclusive.

Sample Input 1

abcde
3
3 ab abc abcd
4 f c cd bcde
2 e de

Sample Output 1

2

For example, doing the following makes the final S S S equal T T T with two yen, which can be shown to be the minimum amount required.

  • For i = 1 i=1 i=1, select abc from bag 1 1 1 and concatenate it to the end of S S S, making S = S= S= abc.
  • For i = 2 i=2 i=2, do nothing.
  • For i = 3 i=3 i=3, select de from bag 3 3 3 and concatenate it to the end of S S S, making S = S= S= abcde.

思路:分组背包,加上substr检查,注意覆盖问题,反向填表

Code

#include <bits/stdc++.h>
#include <string>
#define ll long long
#define int long long
#define pii pair<int, int>
#define pb push_back
#define gcd __gcd
#define lcm(a, b) (a * b) / gcd(a, b)
#define all(a) a.begin(), a.end()
#define mem(a, x) memset(a, x, sizeof(a))
#define f(i, s, e) for (int i = s; i <= e; i++)
#define ff(i, s, e) for (int i = s; i >= e; i--)
#define setbits(x) __builtin_popcount(x)
#define zrobits(x) __builtin_ctzll(x)
#define mod 100000007
#define maxn (ll)(2e5 + 5000)
#define INF 0x3f3f3f3f
using namespace std;

signed main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    string T;
    cin >> T;
    int N;
    cin >> N;

    vector<string> bags[N];
    f(i, 0, N - 1)
    {
        int Ai;
        cin >> Ai;
        for (int j = 0; j < Ai; j++)
        {
            string Si;
            cin >> Si;
            if (Si.size() > 0 && Si.size() <= T.size()) // 排除空字符串和长度大于T的字符串
            {
                bags[i].pb(Si);
            }
        }
    }

    vector<int> dp(T.size() + 10, INF);
    dp[0] = 0;
    f(j, 0, N - 1)
    {
        ff(i, T.size(), 0) // i是现在填了的长度
        {
            for (string s : bags[j])
            {
                if (i + s.size() <= T.size() && T.substr(i, s.size()) == s)
                {
                    dp[i + s.size()] = min(dp[i + s.size()], dp[i] + 1);
                }
            }
        }
    }
    if (dp[T.size()] == INF)
    {
        cout << -1 << endl;
    }
    else
    {
        cout << dp[T.size()] << endl;
    }


    return 0;
}

E - Insert or Erase

Problem Statement

You are given a sequence A = ( A 1 , … , A N ) A=(A_1,\ldots,A_N) A=(A1,,AN) of length N N N. The elements of A A A are distinct.

Process Q Q Q queries in the order they are given. Each query is of one of the following two types:

  • 1 x y : Insert y y y immediately after the element x x x in A A A. It is guaranteed that x x x exists in A A A when this query is given.
  • 2 x : Remove the element x x x from A A A. It is guaranteed that x x x exists in A A A when this query is given.

It is guaranteed that after processing each query, A A A will not be empty, and its elements will be distinct.

Print A A A after processing all the queries.

Constraints

  • 1 ≤ N ≤ 2 × 1 0 5 1 \leq N \leq 2\times 10^5 1N2×105
  • 1 ≤ Q ≤ 2 × 1 0 5 1 \leq Q \leq 2\times 10^5 1Q2×105
  • 1 ≤ A i ≤ 1 0 9 1 \leq A_i \leq 10^9 1Ai109
  • A i ≠ A j A_i \neq A_j Ai=Aj
  • For queries of the first type, 1 ≤ x , y ≤ 1 0 9 1 \leq x,y \leq 10^9 1x,y109.
  • When a query of the first type is given, x x x exists in A A A.
  • For queries of the second type, 1 ≤ x ≤ 1 0 9 1 \leq x \leq 10^9 1x109.
  • When a query of the second type is given, x x x exists in A A A.
  • After processing each query, A A A is not empty, and its elements are distinct.
  • All input values are integers.

Sample Input 1

4
2 1 4 3
4
2 1
1 4 5
2 2
1 5 1

Sample Output 1

4 5 1 3

The queries are processed as follows:

  • Initially, A = ( 2 , 1 , 4 , 3 ) A=(2,1,4,3) A=(2,1,4,3).
  • The first query removes 1 1 1, making A = ( 2 , 4 , 3 ) A=(2,4,3) A=(2,4,3).
  • The second query inserts 5 5 5 immediately after 4 4 4, making A = ( 2 , 4 , 5 , 3 ) A=(2,4,5,3) A=(2,4,5,3).
  • The third query removes 2 2 2, making A = ( 4 , 5 , 3 ) A=(4,5,3) A=(4,5,3).
  • The fourth query inserts 1 1 1 immediately after 5 5 5, making A = ( 4 , 5 , 1 , 3 ) A=(4,5,1,3) A=(4,5,1,3).

思路:根据题意,可以自然的想到双向链表,实现高效的插入和删除

Code

#include <bits/stdc++.h>
#include <iostream>
#include <list>
#define ll long long
#define int long long
#define pii pair<int, int>
#define pb push_back
#define endl '\n'
#define gcd __gcd
#define lcm(a, b) (a * b) / gcd(a, b)
#define all(a) a.begin(), a.end()
#define mem(a, x) memset(a, x, sizeof(a))
#define f(i, s, e) for (int i = s; i <= e; i++)
#define ff(i, s, e) for (int i = s; i >= e; i--)
#define setbits(x) __builtin_popcount(x)
#define zrobits(x) __builtin_ctzll(x)
#define mod 100000007
#define maxn (ll)(2e5 + 5000)
#define INF 0x3f3f3f3f
using namespace std;
// set<int>::iterator it;
list<int> a;
map<int, list<int>::iterator> pos;
signed main(void)
{
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n;
    cin >> n;
    f(i, 1, n)
    {
        int x;
        cin >> x;
        a.pb(x);
        pos[x] = prev(a.end());//获取a.end()的前一个迭代器
    }
    int q;
    cin >> q;
    while (q--)
    {
        int qq;
        cin >> qq;
        if (qq == 1)
        {
            int x, y;
            cin >> x >> y;
            pos[y] = a.insert(next(pos[x]), y);//小技巧,链表的insert()在插入完成后会返回一个迭代器,即在pos[x]的下一个位置(也就是 x 的后面,这个函数会返回一个迭代器,指向新插入的元素 y
        }
        else if (qq == 2)
        {
            int x;
            cin >> x;
            a.erase(pos[x]);
            pos.erase(x);
        }
    }
    for (auto i : a)
    {
        cout << i << " ";
    }
    cout << endl;
    return 0;
}

总结:这次是unrated,打的很放松,所以比平时好很多

  • 21
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
AtCoder Beginner Contest 134 是一场 AtCoder 的入门级比赛,以下是每道题的简要题解: A - Dodecagon 题目描述:已知一个正十二边形的边长,求它的面积。 解题思路:正十二边形的内角为 $150^\circ$,因此可以将正十二边形拆分为 12 个等腰三角形,通过三角形面积公式计算面积即可。 B - Golden Apple 题目描述:有 $N$ 个苹果和 $D$ 个盘子,每个盘子最多可以装下 $2D+1$ 个苹果,求最少需要多少个盘子才能装下所有的苹果。 解题思路:每个盘子最多可以装下 $2D+1$ 个苹果,因此可以将苹果平均分配到每个盘子中,可以得到最少需要 $\lceil \frac{N}{2D+1} \rceil$ 个盘子。 C - Exception Handling 题目描述:给定一个长度为 $N$ 的整数序列 $a$,求除了第 $i$ 个数以外的最大值。 解题思路:可以使用两个变量 $m_1$ 和 $m_2$ 分别记录最大值和次大值。遍历整个序列,当当前数不是第 $i$ 个数时,更新最大值和次大值。因此,最后的结果应该是 $m_1$ 或 $m_2$ 中较小的一个。 D - Preparing Boxes 题目描述:有 $N$ 个盒子和 $M$ 个物品,第 $i$ 个盒子可以放入 $a_i$ 个物品,每个物品只能放在一个盒子中。现在需要将所有的物品放入盒子中,每次操作可以将一个盒子内的物品全部取出并分配到其他盒子中,求最少需要多少次操作才能完成任务。 解题思路:首先可以计算出所有盒子中物品的总数 $S$,然后判断是否存在一个盒子的物品数量大于 $\lceil \frac{S}{2} \rceil$,如果存在,则无法完成任务。否则,可以用贪心的思想,每次从物品数量最多的盒子中取出一个物品,放入物品数量最少的盒子中。因为每次操作都会使得物品数量最多的盒子的物品数量减少,而物品数量最少的盒子的物品数量不变或增加,因此这种贪心策略可以保证最少需要的操作次数最小。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值