写在前面:
希望你自己感谢你自己的坚持

江西财经大学出题组祝大家:越活越年轻,越活越开心


# A - 搞点语法题

# 题目大意

  • 输出字符串

# 题解

直接输出就好

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>
using namespace std;

int main() {
cout << "计算机241陶金杰10.14:\n";
cout << "@全体成员 大家每个人搞点语法题出来,然后最后放道思维压一下吧\n\n";
cout << "五德废墟:\n";
cout << "猫猫猫猫猫\n";
cout << "猫火猫火猫\n";
cout << "猫猫猫猫猫\n";
cout << "猫猫口猫猫\n";
cout << "猫猫猫猫猫\n";
return 0;
}

备注:总共 wa 了一千多发,主要问题集中在

  1. 换行处理不当:如 C 语言中直接在字符串内换行导致语法错误,或空行数量不符(多输出空行、遗漏关键空行);
  2. 多余空格:部分代码在空行中添加了不必要的空格;
  3. 字符串语法错误:尝试在 printf 字符串中直接换行,不符合 C 语言语法规范;
  4. 内容细节偏差:如文字表述多出无关字词(如 “大家每个人都搞点” 中的 “都”)。

# B - 陶姐姐的单词计数

# 题目大意

题目要求统计输入的若干个字符串(每个字符串为一个单词,不含空格)的总个数。输入的单词数量未知,只需输出单词的总个数即可。

# 数据范围

无明确数据范围限制,需处理任意数量的单词输入。

# 题解

解决该问题的关键是读取输入中的所有单词并计数。可以通过循环持续读取单词,每成功读取一个单词就将计数器加 1,直到没有更多输入为止。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <string>
using namespace std;

int main() {
string word;
int count = 0;
// 循环读取单词,直到输入结束
while (cin >> word) {
count++;
}
cout << count << endl;
return 0;
}

# C - 有反转?

# 题目大意

给你一个字符串 s,输出其反转后的字符串

# 题解

简单理解一下就可以知道,我们只需要倒着输出 s 的每一个字符即可,用 for 循环从 n 枚举到 1 即可,其中 n 是字符串 s 的长度。唯一需要注意的就是有空格,我们需要使用 getline。
但是我们还能使用 reverse 函数快速实现反转操作,具体可以百度看看。

1
2
3
4
5
6
7
8
9
10
11
#include <bits/stdc++.h>
using namespace std;

signed main()
{
string s;
getline(cin,s);
reverse(s.begin(),s.end());
cout << s << '\n';
return 0;
}

# D - 哈基鱼爬山

# 题目大意

给定长度为 nn 的数字序列,判断出现了多少个 “山顶”(可能会有数值相同的一段连续区间)

# 数据范围

1n2×105,109ai1091 \leq n \leq 2 \times 10^5, -10^9 \leq a_i \leq 10^9

# 题解

如果没有数值相同的连续区间,显然我们循环遍历判断下式:

ai1<ai<ai+1(2in1)a_{i-1} < a_i < a_{i+1}(2 \leq i \leq n - 1)

记录符合上式的 aia_i 的个数就可以得出答案。
但是哈基鱼可能休息一段时间,这该怎么办呢?
一种简单的做法就是去重,我们可以把因为休息导致的数值相同的连续区间缩成一个点,这样就可以通过上面的做法得出答案了。
对于去重,我们可以遍历原数组,将一个点存入另一个数组后,跳过之后连续的值,然后就得到了一个去重后的数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
//#define int long long
using namespace std;
const int N = 2e5 + 5;

int n;
int a[N], b[N];

signed main() {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
int k = 0;
for (int i = 1; i <= n; ) { //去重;
b[++k] = a[i];
while (a[i] == b[k]) i++;
}
if (k <= 2) cout << 0 << '\n';
else {
int ans = 0;
for (int i = 2; i <= k - 1; i++) {
if (b[i] > b[i - 1] && b[i] > b[i + 1]) ans++;
}
cout << ans << '\n';
}
return 0;
}

ps:当然直接用 ai1ai<ai+1(2in1)a_{i-1} \leq a_i < a_{i+1}(2 \leq i \leq n - 1) 判断也可以 (doge)

# E - 九条可怜的书写条件

# 题目大意

  • 给定了一个字符串的书写格式,求出这个字符串省略的数字个数

# 题解

字符串处理题
这道题用 C++C++ 没有 CC 方便,主要考查对 CC 语言的输入输出的掌握程度
scanfscanf 中的格式字符串 "%d,%d,...,%d" 需要与输入数据严格匹配
将三个数字分别赋值给变量 a,b,ca,b,c
被省略的数字个数就是 cb1c-b-1

1
2
3
4
5
void solve() {
int a, b, c;
scanf("%d,%d,...,%d", &a, &b, &c);
printf("%d", c - b - 1);
}

# F - 相遇天使

# 题目大意

yiko\tt{yiko}mohao\tt{mohao} 在户外玩一个很神秘的游戏:地上有 nn 个互不相交且不相切的圈,二人初始都不站在圈上。yiko\tt{yiko} 站在 (x1,y1)(x_1,y_1)mohao\tt{mohao} 站在 (x2,y2)(x_2,y_2)mohao\tt{mohao} 可以在不离开地面的情况下以任意路径奔向 yiko\tt{yiko},问 mohao\tt{mohao} 最少要穿过圈几次?

# 题解

我们考虑每一个圈和两个点之间的关系:

  1. 两个点在圈内;
  2. 两个点中的一个点在圈内;
  3. 两个点都在圈外。
    不难发现对于情况 1 和情况 3,我们的路径不需要穿过圈,而对于情况 2,我们是必然要穿过这个圈的。因此枚举每一个圈和这两个点之间的关系即可。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #include <bits/stdc++.h>
    using namespace std;

    using i64 = long long;
    void solve() {
    int n;
    cin >> n;
    int x1, y1, x2, y2;
    cin >> x1 >> y1 >> x2 >> y2;
    int ans = 0;
    for (int i = 0; i < n; i++) {
    int x, y, r;
    cin >> x >> y >> r;
    int d1 = (x - x1) * (x - x1) + (y - y1) * (y - y1);
    int d2 = (x - x2) * (x - x2) + (y - y2) * (y - y2);
    ans += (d1 < r * r) ^ (d2 < r * r);
    }
    cout << ans << "\n";
    }

    signed main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    int T = 1;
    while (T--)
    solve();
    return 0;
    }

# G - God of Reversal Requiem

# 题目大意

  • n21n * 2 - 1 个数,每次可以让恰好 nn 个数乘以 1-1,求数组最大和。

# 题解

经典 trick。
思路:容易发现,连续操作两次,每次选择 n1n-1 个相同的位置,会留有两个不同位置,等价于将那两个数变成相反数。
比如对于 {4,4,5,5,5}(n=3)\{ -4,-4,5,5,5 \}(n=3)

  • 先选择序号 1,3,41,3,4,序列变为 \
  • 再选择序号 2,3,42,3,4,序列变为 \

所以如果负数个数为偶数,这样操作最后全是正数。
如果负数个数为奇数,nn 也是奇数,操作一次可以让负数变成偶数个,然后重复上面的操作。

  • 比如 {4,5,5,5,5}(n=3)\{ -4,5,5,5,5 \}(n=3),选择序号 1,2,31,2,3,让负数个数变偶数,即 {4,5,5,4,4}\{ 4,-5,-5,4,4 \},然后变成第一种情况。

nn 是偶数,反复操作后可以让负数变成一个。

  • 比如 {4,5,5}(n=2)\{ -4,5,5 \}(n=2),无论怎么操作都会剩下一个负数。

注意数据范围,最坏情况下 1e51e9=1e14>>>1e91e5 * 1e9 =1e14>>>1e9,所以开 long long

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <bits/stdc++.h>
using namespace std;
#define int long long
int a[(int)2e5+500];
signed main()
{
int n;
cin >> n;
int m = n * 2 - 1;
int num=0; //计算负数个数
for(int i=1;i<=m;i++)
{
cin >> a[i];
if (a[i] < 0)
{
num++;
}
a[i] = abs(a[i]); //因为大部分数最后都变成正数,为了方便处理先全部取绝对值
}

if (num % 2 == 0) //负数个数为偶数,最后可以变成全正
{
cout << accumulate(a + 1, a + 1 + m, 0ll);
}
else
{
if (n % 2) //负数个数为奇数且n为奇数,可以通过一次操作让负数个数变成偶数,然后同上
{
cout << accumulate(a + 1, a + 1 + m, 0ll);
}
else //负数个数为奇数且n为偶数,则会有一个负数,所以排序后让最小的为负数保证总和最大
{
sort(a + 1, a + 1 + m);
cout << -a[1] + accumulate(a + 2, a + 1 + m, 0ll);
}
}
}

# H - 我的歌单呢?

# 题目大意

小羊歌单里本来有 nn 个整数 b1,b2,,bnb_1, b_2, \dots, b_n
但是 mohao\tt{mohao} 打乱了这些数字,并告诉小羊 nn 个值 a1,a2,,ana_1, a_2, \dots, a_n,它们是通过以下过程定义的:

  • mohao\tt{mohao} 最初将 aia_i 设为 00
  • 接着,mohao\tt{mohao}bib_i 加到 aia_i 上,减去 bi+1b_{i+1},加上 bi+2b_{i+2},依此类推,直到第 nn 个数。

小羊回来只看到了被打乱的了 a1,a2,,ana_1, a_2, \dots, a_n,希望帮你恢复出原来的 b1,b2,,bnb_1, b_2, \dots, b_n。请帮帮小羊?

# 题解

根据题意我们可以写出

\begin{alignat*}{6} b_1 &= a_1 &&- a_2 &&+ a_3 &&- \dotsb &&+ (-1)^{n-1} a_n \\ b_2 &= &&+ a_2 &&- a_3 &&+ \dotsb &&+ (-1)^{n-2} a_n \\ b_3 &= && &&+ a_3 &&- \dotsb &&+ (-1)^{n-3} a_n \\ \vdots\\ b_n &= && && && && +(-1)^{n-n} a_n \end{alignat*}

同理我们一直写到 bnb_{n}
我们可以发现每个 $$b_i}=a{i}-(a_{i+1}-a_{i+2} \dotsb+ (-1)({n-i-1)a_n)$$
而括号的位置就是 bi+1b_{i+1}
因此我们推得 $$b_{i}=a_{i}-b_{i+1}$$
所以 $$a_{i}=b_{i}+b_{i+1}$$
因此 code:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 9;
typedef long long ll;
int a[N];
int main() {
int n; cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n; i++) {
cout << a[i] + a[i + 1] << ' ';
}
return 0;
}