2023 年新生杯(第一届鸭鸭杯)题解

Ivan_Chien

C++

A

签到题。

 1#include <iostream>
 2#include <climits>
 3 
 4int main()
 5{
 6    int n, t;
 7    std::cin >> n >> t;
 8 
 9    int prev = INT_MIN / 2;
10    int curr;
11    while (std::cin >> curr)
12    {
13        if (curr - prev <= t)
14        {
15            std::cout << curr << std::endl;
16            return 0;
17        }
18        prev = curr;
19    }
20 
21    std::cout << -1 << std::endl;
22     
23    return 0;
24}

B

模拟。有多对可消时,易证消的顺序不影响最后结果。

 1#include <bits/stdc++.h>
 2using i64 = long long;
 3 
 4int main()
 5{
 6    int n;
 7    std::cin >> n;
 8    std::vector<int> v(n);
 9 
10    for (int i = 0; i < n; ++i)
11    {
12        std::cin >> v[i];
13    }
14 
15    i64 ans = 0;
16    bool flag = true;
17    while (flag)
18    {
19        flag = false;
20        for (int i = 0; i + 1 < n; ++i)
21        {
22            if (v[i] == v[i + 1])
23            {
24                flag = true;
25                ans += 1LL * v[i];
26                v.erase(v.begin() + i);
27                v.erase(v.begin() + i);
28                n -= 2;
29                break;
30            }
31        }
32    }
33 
34    std::cout << ans << std::endl;
35     
36    return 0;
37}

C

两两相消,使用 map 来维护数的库存。排序后用双指针亦可。

 1#include <bits/stdc++.h>
 2using i64 = long long;
 3 
 4int main()
 5{
 6    int n, sum;
 7    std::cin >> n >> sum;
 8 
 9    std::map<int, int> cnt;
10    i64 ans = 0;
11    for (int i = 0; i < n; ++i)
12    {
13        int a;
14        std::cin >> a;
15        if (cnt[sum - a] > 0)
16        {
17            --cnt[sum - a];
18            ++ans;
19        }
20        else
21        {
22            ++cnt[a];
23        }
24    }
25 
26    std::cout << ans << std::endl;
27     
28    return 0;
29}

D

统计字母数量是否足够即可。

 1#include <bits/stdc++.h>
 2using i64 = long long;
 3 
 4int main()
 5{
 6    int n, m;
 7    std::string a, b;
 8    std::cin >> n >> m >> a >> b;
 9 
10    std::map<char, int> cnt;
11    for (auto c : a)
12    {
13        ++cnt[c];
14    }
15 
16    for (auto c : b)
17    {
18        if (cnt[c] <= 0)
19        {
20            std::cout << "NO" << std::endl;
21            return 0;
22        }
23        --cnt[c];
24    }
25 
26    std::cout << "YES" << std::endl;
27     
28    return 0;
29}

E

贪心。从 0 出发,对石头高度排序,每次往序列的另一头跳即可。

 1#include <bits/stdc++.h>
 2using i64 = long long;
 3 
 4int main()
 5{
 6    int n, m;
 7    std::cin >> n >> m;
 8    std::vector<int> v(n);
 9 
10    for (int i = 0; i < n; ++i)
11    {
12        std::cin >> v[i];
13    }
14     
15    std::sort(v.begin(), v.end());
16 
17    int left = 0, right = n;
18    int currH = 0;
19    i64 ans = 0;
20    while (left < right)
21    {
22        int d1 = std::abs(currH - v[left]);
23        int d2 = std::abs(currH - v[right - 1]);
24        if (d1 > d2)
25        {
26            ans += 1LL * d1;
27            currH = v[left];
28            ++left;
29        }
30        else   // d1 < d2, NEVER EQUAL
31        {
32            ans += 1LL * d2;
33            currH = v[right - 1];
34            --right;
35        }
36    }
37 
38    if (ans <= m)
39    {
40        std::cout << "算你厉害" << std::endl;
41    }
42    else
43    {
44        std::cout << ans - m << std::endl;
45    }
46     
47    return 0;
48}

F

枚举所有区间和即可,用前缀和做个简单优化。

 1#include <bits/stdc++.h>
 2using i64 = long long;
 3 
 4int main()
 5{
 6    int n, m;
 7    std::cin >> n >> m;
 8 
 9    std::vector<int> pref(n + 1);
10    for (int i = 1; i <= n; ++i)
11    {
12        int a;
13        std::cin >> a;
14        pref[i] = a + pref[i - 1];
15    }
16 
17    i64 ans = 0;
18    for (int i = 1; i <= n; ++i)
19    {
20        for (int j = 0; j < i; ++j)
21        {
22            if (pref[i] - pref[j] == m)
23            {
24                ++ans;
25            }
26        }
27    }
28 
29    std::cout << ans << std::endl;
30     
31    return 0;
32}

G

模拟。

 1#include <bits/stdc++.h>
 2using i64 = long long;
 3
 4int main()
 5{
 6    int n, m;
 7    std::cin >> n >> m;
 8 
 9    std::vector mat(n, std::vector(m, 0));
10 
11    for (auto& v : mat)
12    {
13        for (auto& a : v)
14        {
15            std::cin >> a;
16        }
17    }
18 
19    int cq;
20    std::cin >> cq;
21    std::vector<int> q(m);
22    while (cq--)
23    {
24        int ans = 0;
25        for (int i = 0; i < m; ++i)
26        {
27            std::cin >> q[i];
28        }
29     
30        for (int i = 0; i < n; ++i)
31        {
32            bool flag = true;
33            for (int j = 0; j < m; ++j)
34            {
35                if (q[j] != -1 && q[j] != mat[i][j])
36                {
37                    flag = false;
38                    break;
39                }
40            }
41            if (flag) ++ans;
42        }
43        std::cout << ans << std::endl;
44    }
45     
46    return 0;
47}

H

简单构造。

 1#include <bits/stdc++.h>
 2using i64 = long long;
 3 
 4int main()
 5{
 6    i64 n, m;
 7    std::cin >> n >> m;
 8    i64 ans = 0;
 9 
10    while (n != m)
11    {
12        if (n < m)
13        {
14            std::swap(n, m);
15        }
16        i64 f = n / m;
17        if (f * m == n) --f;
18        n -= f * m;
19        ans += f;
20    }
21 
22    std::cout << ans << std::endl;
23     
24    return 0;
25}

i

前缀和。

 1#include <bits/stdc++.h>
 2using i64 = long long;
 3 
 4int main()
 5{
 6    i64 n, w;
 7    std::cin >> n >> w;
 8 
 9    std::vector<int> pref(n + 1);
10    for (int i = 1; i <= n; ++i)
11    {
12        int a;
13        std::cin >> a;
14        pref[i] = a + pref[i - 1];
15    }
16 
17    int max = -1;
18    for (int i = w; i <= n; ++i)
19    {
20        max = std::max(max, pref[i] - pref[i - w]);
21    }
22    std::cout << max << std::endl;
23     
24    return 0;
25}

J

数据范围小,直接暴力。正统做法大概是 unique 后做区间 DP。

 1#include <bits/stdc++.h>
 2using i64 = long long;
 3 
 4int main()
 5{
 6    std::string s;
 7    std::cin >> s;
 8 
 9    int ans_odd = 0, ans_even = 0;
10    int n = s.length();
11    for (int d = 1; d <= n; ++d)
12    {
13        for (int i = 0; i + d <= n; ++i)
14        {
15            auto ss = s.substr(i, d);
16            ss.erase(std::unique(ss.begin(), ss.end()), ss.end());
17            int nn = ss.length();
18            bool flag = true;
19            for (int i = 0; i < nn / 2; ++i)
20            {
21                if (ss[i] != ss[nn - 1 - i])
22                {
23                    flag = false;
24                    break;
25                }
26            }
27            if (flag)
28            {
29                if (d & 1) ++ans_odd;
30                else ++ans_even;
31            }
32        }
33    }
34 
35    std::cout << ans_even << ' ' << ans_odd << std::endl;
36     
37    return 0;
38}

Python 参考

C

 1from collections import Counter
 2 
 3n, m = map(int, input().split())
 4c = Counter()
 5ans = 0
 6for _ in range(n):
 7    a = int(input())
 8    if c[m - a] > 0:
 9        c[m - a] -= 1
10        ans += 1
11    else:
12        c[a] += 1
13print(ans)

Java 参考

A

 1import java.util.Scanner;
 2 
 3public class Main {
 4    public static void main(String[] args) {
 5        Scanner s = new Scanner(System.in);
 6        int n = s.nextInt();
 7        int m = s.nextInt();
 8        int prev = -114514191;
 9        for (int i = 0; i < n; i++)  {
10            int a;
11            a = s.nextInt();
12            if (a - prev <= m) {
13                System.out.println(a);
14                return ;
15            }
16            prev = a;
17        }
18        System.out.println(-1);
19    }
20}