CSP-J 2026 第二轮入门组真题解析(第一题 、旅游)



CSP-J/S 2026 第二轮初赛题:旅游

今天我们来解决一道有趣的座位判断题。想象一下:两位同学买了火车票,我们要根据他们的座位号,判断他们是不是坐在同一节车厢、同一排,以及座位之间的关系。

这道题的关键不是计算距离,而是按照题目要求,一层一层地判断。


一、先看懂座位布局

每一排有 5 个座位:

复制代码
靠窗一侧       过道       另一侧
 A   B   C   |   D   F

注意:

  • A、B、C 在过道左边;

  • D、F 在过道右边;

  • C 和 D 虽然紧挨着过道两侧,但不算相邻座位;

  • 同一排的座位号前两位相同,例如 01A、01C 都在第 01 排。

一张座位票由两部分组成:

复制代码
02  01C
│   │ └─ 座位字母
│   └─── 排号
└─────── 车厢号

例如,02 01C 表示 02 号车厢、01 排、C 座。


二、题目要判断哪四件事?

题目给出两张票:c1 s1 和 c2 s2,要求输出一个由 4 个数字组成的字符串。

从左到右,分别判断:

  1. 是否在同一节车厢

  2. 是否在同一节车厢、同一排

  3. 是否在同一节车厢、同一排,而且在过道同一侧

  4. 是否在同一节车厢、同一排、过道同一侧,并且座位相邻

每个条件成立就输出 1,不成立就输出 0。

要特别注意:后面的条件越来越严格。比如,虽然两张票都在过道左侧,但如果不在同一节车厢、同一排,第三位仍然应该是 0。


三、一步一步判断

第一步:判断是否同一节车厢

直接比较车厢号:

复制代码
bool ans1 = (c1 == c2);

如果相同,ans1 就是 true,输出时会变成 1;否则是 0。


第二步:判断是否同一排

座位字符串的前两位是排号。

例如:

  • 01A 的排号是 01

  • 01D 的排号也是 01

  • 02A 的排号是 02

因此可以比较两个座位字符串的前两位:

复制代码
bool sameRow = (s1.substr(0, 2) == s2.substr(0, 2));
bool ans2 = ans1 && sameRow;

这里的 && 表示"并且"。所以第二个条件要求:同一节车厢,并且同一排。


第三步:判断是否在过道同一侧

先判断每个座位在过道哪一边:

复制代码
bool left1 = (s1[2] == 'A' || s1[2] == 'B' || s1[2] == 'C');
bool left2 = (s2[2] == 'A' || s2[2] == 'B' || s2[2] == 'C');

如果座位字母是 A、B、C,就是左侧;否则就是右侧。

然后判断两人是否在同一侧:

复制代码
bool sameSide = (left1 == left2);
bool ans3 = ans2 && sameSide;

重点:不能只判断 sameSide。两人即使都在左侧,也必须先满足同一车厢、同一排,第三位才能输出 1。


第四步:判断是否相邻

为了判断座位是否相邻,我们给每一侧的座位编号:

复制代码
左侧:A=1,B=2,C=3
右侧:D=1,F=2

这样:

  • A 和 B 的编号差是 1,属于相邻;

  • B 和 C 的编号差是 1,属于相邻;

  • D 和 F 的编号差是 1,属于相邻;

  • C 和 D 虽然挨着过道,但属于两侧,不能算相邻。


先写一个函数,把座位字母转换成编号:

复制代码
int pos(char c) {
    if (c == 'A') return 1;
    if (c == 'B') return 2;
    if (c == 'C') return 3;
    if (c == 'D') return 1;
    if (c == 'F') return 2;
    return 0;
}

再判断编号差是否为 1:

复制代码
bool adjacent = (abs(pos(s1[2]) - pos(s2[2])) == 1);
bool ans4 = ans3 && adjacent;

注意,最后一位不能只看座位编号差。必须先满足 ans3,也就是同一车厢、同一排、过道同一侧。


四、完整 C++ 程序

复制代码
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;

// 把座位字母转换成这一侧的座位编号
int pos(char c) {
    if (c == 'A') return 1;
    if (c == 'B') return 2;
    if (c == 'C') return 3;

    if (c == 'D') return 1;
    if (c == 'F') return 2;

    return 0;
}

int main() {
    string c1, s1, c2, s2;
    cin >> c1 >> s1 >> c2 >> s2;

    // 第1位:是否在同一节车厢
    bool ans1 = (c1 == c2);

    // 判断是否同一排
    bool sameRow = (s1.substr(0, 2) == s2.substr(0, 2));

    // 第2位:同一车厢,并且同一排
    bool ans2 = ans1 && sameRow;

    // 判断两人是否都在过道左侧
    bool left1 = (s1[2] == 'A' || s1[2] == 'B' || s1[2] == 'C');
    bool left2 = (s2[2] == 'A' || s2[2] == 'B' || s2[2] == 'C');

    // 判断是否在过道同一侧
    bool sameSide = (left1 == left2);

    // 第3位:同一车厢、同一排、过道同一侧
    bool ans3 = ans2 && sameSide;

    // 判断座位编号是否相差1
    bool adjacent = (abs(pos(s1[2]) - pos(s2[2])) == 1);

    // 第4位:前面三个条件都成立,并且座位相邻
    bool ans4 = ans3 && adjacent;

    cout << ans1 << ans2 << ans3 << ans4 << endl;

    return 0;
}

五、用例子检查程序

输入:

复制代码
02 01C 02 01D

两张票在同一车厢、同一排,但 C 在过道左边,D 在过道右边。

判断 结果 原因
同一车厢 1 都是 02 号车厢
同一车厢、同一排 1 都是 01 排
同一侧 0 C、D 在过道两侧
相邻座位 0 不在同一侧

输出:

复制代码
1100

再看:

复制代码
02 02B 02 02C

两人同车厢、同一排、同在过道左侧,而且 B、C 相邻,所以输出:

复制代码
1111

六、这道题最容易错在哪里?

记住这句话:

后面的判断必须建立在前面的条件已经成立的基础上。

尤其是第三位和第四位:

  • 第三位不能只判断"是否在过道同一侧";

  • 第四位不能只判断"座位编号差是不是 1";

  • C 和 D 在过道两侧,不算相邻。

把条件一层一层组合起来,就能避免这些错误。


相关推荐
xiaoye-duck42 分钟前
《C++ 项目:手写大模型接入 SDK》Gemini接口设计(上):初始化、全量响应实现和测试
开发语言·网络·c++·语言模型
UIU1145 小时前
P1481 魔族密码
c++·算法·动态规划
闻缺陷则喜何志丹11 小时前
【C++特性】四种类型转
c++·算法·类型转换
apcipot_rain14 小时前
C++转Java日记(02)
java·开发语言·c++
杜 硕14 小时前
从零开始的C++生活——第七讲——02
开发语言·c++·生活
Rabitebla1 天前
【Linux 底层原理】进程(十):进程等待详解---从僵尸进程到 wait、waitpid 与 status
linux·c++·笔记·学习·visual studio
西西弗Sisyphus1 天前
C++ 超时互斥锁(Timed Mutex):std::timed_mutex 与 std::unique_lock
c++
今天要早睡_1 天前
C++01_入门基础复习
开发语言·c++
Fuyo_11191 天前
C++ 运行时多态与虚函数机制全面剖析【面试重点】
开发语言·c++·面试