蓝桥杯101 拉马车

目录

前置知识

[1. 使用 deque 实现玩家手牌管理](#1. 使用 deque 实现玩家手牌管理)

[2. 使用 vector 实现桌面牌堆管理](#2. 使用 vector 实现桌面牌堆管理)

[3. 使用数组映射实现牌面位置索引](#3. 使用数组映射实现牌面位置索引)

[4. 游戏轮转流程与 turn 状态管理](#4. 游戏轮转流程与 turn 状态管理)

[5. 游戏状态编码与字符串表示](#5. 游戏状态编码与字符串表示)

[6. 使用无序集合实现状态判重与循环检测](#6. 使用无序集合实现状态判重与循环检测)

[7. 终止条件](#7. 终止条件)

代码演变

[Step 0:最小骨架](#Step 0:最小骨架)

[Step 1:把手牌建成队列结构](#Step 1:把手牌建成队列结构)

[Step 2:加入桌面牌堆 + 轮流出牌框架](#Step 2:加入桌面牌堆 + 轮流出牌框架)

[Step 3:加入快速判断桌面是否已有该牌](#Step 3:加入快速判断桌面是否已有该牌)

[Step 4:实现赢牌收回一段桌面牌](#Step 4:实现赢牌收回一段桌面牌)

[Step 5:补齐游戏结束条件和输出胜者手牌](#Step 5:补齐游戏结束条件和输出胜者手牌)

[Step 6:加入严格判环](#Step 6:加入严格判环)

简单解法


题目链接:

前置知识

1. 使用 deque 实现玩家手牌管理

1. 目标与建模

使用双端队列(deque)对"玩家手牌"进行建模,实现从队头出牌和从队尾收牌的操作。要求能够实现从队头出牌和从队尾收牌的基本操作。

2. 核心操作(C++ STL deque)

初始化:deque<char> A(s.begin(), s.end());

将字符串或序列初始化为 deque。

访问队头元素:A.front()

返回队头元素的引用。

队头出队:A.pop_front()

移除队头元素。

队尾入队:A.push_back(x)

在队尾插入元素 x。

判断队列是否为空:A.empty()

返回布尔值表示 deque 是否为空。

3. 为什么使用 deque?

两端操作的高效性:玩家手牌需支持从队头出牌(pop_front)和从队尾收牌(push_back)

deque 在两端插入和删除的时间复杂度均为 O(1),而 vector 在头部删除(erase(begin()))需要移动所有后续元素,代价为 O(n)。因此,deque 天生适合此类场景。

4. 自测

初始手牌:

A = [K, 8, X](左侧为队头)

要求:

玩家出一张牌(牌值为队头元素 K),并将其从手牌中移除。

玩家依次收回两张牌 2 和 7(按顺序从队尾加入)

cpp 复制代码
// 1. 出牌:从队头移除元素
char x = A.front();  // x = 'K'
A.pop_front();        // 移除队头,A 变为 [8, X]

// 2. 收牌:依次从队尾加入新牌
A.push_back('2');     // A 变为 [8, X, 2]
A.push_back('7');     // A 变为 [8, X, 2, 7]

2. 使用 vector 实现桌面牌堆管理

1. 目标与建模

使用 vector 对"桌面牌堆"进行建模,实现向桌面顶部压牌、查看顶部牌面、获取牌堆长度以及截取特定区间的操作。要求能够实现向桌面顶部压牌、查看顶部牌面、获取牌堆长度以及截取特定区间的操作。

2. 核心操作(C++ STL vector)

向桌面顶部压牌:table.push_back(x)

在 vector 尾部(牌堆顶部)插入元素 x。

查看桌面顶部牌面:table.back()

返回顶部元素的引用。

获取桌面牌堆长度:table.size()

返回当前牌堆中牌的张数。

截取牌堆:table.resize(k)

将牌堆大小调整为 k,若 k < 当前大小,则丢弃尾部的牌(从顶部开始移除)

随机访问:table[i]

返回索引 i 处元素的引用(i = 0 表示桌面最底部的牌)

3. vector 作为栈的语义

索引与位置对应关系:

table[0]:牌堆最底部的牌(最早放置)

table.back():牌堆最顶部的牌(最近放置)

截断操作的直观性:当需要"收走顶部若干张牌"时,牌堆剩余部分即为原始序列的前缀。使用 resize(k) 可直接截断尾部,保留前 k 张牌,操作自然高效。

4. 自测

初始牌堆:

table = [K, 2, 8, 7](K 为底部,7 为顶部)

操作要求:

向桌面顶部压入一张新牌 X。

将桌面牌堆截断,仅保留最底部的 3 张牌。

cpp 复制代码
// 1. 压牌:向顶部添加新牌
table.push_back('X');  // table 变为 [K, 2, 8, 7, X]

// 2. 截断:保留前 3 张牌(索引 0, 1, 2)
table.resize(3);       // table 变为 [K, 2, 8]

3. 使用数组映射实现牌面位置索引

1. 目标与建模

使用数组作为哈希表记录牌面在桌面上的位置信息。通过 pos[ch] 数组实现从牌面字符到其桌面位置的快速映射,要求能够正确初始化、更新和查询位置信息,并理解在游戏规则下的正确更新时机。要求能够正确初始化、更新和查询位置信息,并理解在游戏规则下的正确更新时机。

2. 核心操作

初始化数组:fill(pos, pos + 128, -1);

将数组所有元素初始化为 -1,表示该牌面当前不在桌面上。

位置更新:pos[ch] = index;

记录字符 ch 在桌面上的位置索引 index。

位置查询:int old = pos[(unsigned char)ch];

获取字符 ch 当前在桌面上的位置,若返回 -1 则表示该牌不在桌面。

3. 关键理解

字符作为数组下标:

C/C++ 中字符本质是整数,可直接作为数组下标。

数组作为哈希表的优势:

当键值范围固定且较小(ASCII 字符集)时,数组比 map 或 unordered_map 具有更好的缓存局部性和访问效率,时间复杂度为 O(1)。

更新时机的严谨性:

在游戏规则中,当桌面上出现重复牌面时,需要先根据旧位置触发收牌逻辑,然后才能更新位置信息。直接覆盖旧位置会导致收牌逻辑错误。

4. 自测

初始桌面:

table = [K, 2, 8, 7](索引分别为 0, 1, 2, 3)

维护的位置数组:

pos['K'] = 0

pos['2'] = 1

pos['8'] = 2

pos['7'] = 3

问题:

(1) 当前 pos['8'] 的值是多少?

(2) 若向桌面顶部压入一张 '8',在触发收牌规则前,是否应该立即将 pos['8'] 更新为新位置?

解答:

(1) pos['8'] = 2(对应桌面索引 2 的位置)

(2) 不应该直接更新。正确流程应为:

先查询旧位置:int old = pos['8'];(获取值 2)

根据游戏规则处理收牌逻辑(使用旧位置)

清理或更新相关牌面的位置信息

最后更新 pos['8'] 为新位置(如果新牌仍留在桌面)

4. 游戏轮转流程与 turn 状态管理

1. 目标与建模

游戏模拟的完整轮转流程包括正常出牌、收牌触发条件、手牌更新、桌面状态维护以及回合切换机制。要求能够准确描述并实现每一轮的标准操作流程。

2. 一轮标准流程

设当前玩家手牌队列为 me,对方玩家为 op:

假设在玩家打出 "2" 之前,游戏的初始状态是:

模块 具体内容
桌面(table) [K(0), 2(1), 8(2), 7(3)](括号里是每个牌的索引,0 是最底部,3 是顶部)
位置数组(pos) pos['K']=0、pos['2']=1、pos['8']=2、pos['7']=3(记录每张牌在桌面的位置)
当前玩家 假设是 "我(me)",手牌里有一张 "2"(准备打出)
回合状态(turn) 假设 turn=0 代表 "我" 的回合,turn=1 代表对手(op)的回合

第 1 步:出牌

char x = me.front(); // 获取队头牌面

me.pop_front(); // 移除队头

table.push_back(x); // 压入桌面顶部(table末尾)

最后一行代码可看上面2.3

执行后结果:

桌面(table)变成:[K(0), 2(1), 8(2), 7(3), 2(4)](新增的 2 在索引 4,是桌面最新 / 最顶部的牌)

手牌(me):少了一张 "2"

pos 数组:暂时没变化(还是 pos['2']=1)

第 2 步:查询历史位置

int old = pos[x]; // 查询该牌面是否已在桌面

关键判断:

old == -1:牌之前不在桌面,则不触发收牌,切换回合;

old >= 0:牌之前在桌面(这里 old=1≥0),则触发收牌,当前玩家继续出牌。

第 3 步:分支处理

情况 A:未触发收牌 (old == -1)

pos[x] = table.size() - 1; // 记录新位置

turn ^= 1; // 切换回合,轮到对方出牌

异或(^)的基础规则是两个二进制位相同则结果为 0,不同则结果为 1。

turn 的当前值 turn ^ 1 的结果 实际含义
0 0 ^ 1 = 1 从 "我的回合" 切到 "对手"
1 1 ^ 1 = 0 从 "对手回合" 切回 "我"

情况 B:触发收牌 (old >= 0)
子步骤 1:逆序收牌(把桌面的牌拿回自己手牌)

核心规则:从桌面最顶部(新 2,索引 4)到旧 2(索引 1)的所有牌,逆着拿回来(先拿顶部的,再拿下面的)

for (int i = table.size() - 1; i >= old; --i) {

me.push_back(table[i]); // 把table[i]加到自己手牌队尾

pos[table[i]] = -1; // 这些牌被收走了,pos标记为-1(不在桌面)

}

执行后结果:

手牌(me):队尾新增了 [2,7,8,2](逆序收牌的结果)

pos 数组:pos['2']=-1、pos['7']=-1、pos['8']=-1(只有 pos ['K']=0 还在)

子步骤 2:更新桌面状态(截断桌面)

核心动作:把桌面中 "被收走的牌" 删掉,只保留 old(1)之前的牌(索引 0)

table.resize(old); // old=1,所以table只保留前1个元素(索引0)

可看上面2.4,截断操作会包括自身,即old

执行后结果:

桌面(table)变成:[K(0)](只留了最开始的 K,其他都被收走了)

子步骤 3:回合控制(谁继续出牌)

核心规则:触发收牌时,当前玩家 "赢了这轮",继续出牌,所以turn不变。

初始 turn=0(我的回合),现在还是 turn=0 ,所以接下来还是我出牌。

3. 关键理解

回合切换条件:

未触发收牌时,回合切换 (turn ^= 1)

触发收牌时,回合不变(赢牌玩家继续出牌)

收牌顺序:必须从桌面顶部向底部(从新到旧)逆序收牌

状态同步:收牌时需要同步更新位置数组,将被收走的牌面标记为不在桌面 (pos[...] = -1)

5. 游戏状态编码与字符串表示

1. 目标与建模

将复杂游戏局面编码为字符串,用于判重检测和状态记录。要求能够将回合信息、玩家手牌序列和桌面牌堆组合成唯一的字符串标识。

2. 核心编码方法

cpp 复制代码
string state;                    // 状态字符串
state.reserve(预估长度);          // 预分配空间提升性能

// 1. 编码回合信息
state.push_back(char('0' + turn));  // turn 转换为字符 '0' 或 '1'
state.push_back('|');               // 分隔符

// 2. 编码玩家A手牌序列
state.append(A.begin(), A.end());   // 追加A的手牌
state.push_back('|');               // 分隔符

// 3. 编码玩家B手牌序列
state.append(B.begin(), B.end());   // 追加B的手牌
state.push_back('|');               // 分隔符

// 4. 编码桌面牌堆序列
state.append(table.begin(), table.end());  // 追加桌面牌堆

3. 关键设计原则

回合信息必须编码:相同的牌序但不同回合玩家会导致不同的游戏走向,因此必须包含 turn 信息

分隔符的必要性:使用分隔符避免序列边界歧义,确保编码的唯一性,比如"12|3" 与 "1|23" 代表完全不同的状态

顺序一致性:编码顺序应固定为:turn、A手牌、B手牌、桌面牌堆

4. 自测

游戏状态:

当前回合:turn = 1(玩家B的回合)

玩家A手牌:A = [K, 8]

玩家B手牌:B = [2]

桌面牌堆:table = [7, X]

编码实现:

cpp 复制代码
string state;
state.reserve(10);  // 预估长度

state.push_back('1');  // turn=1
state.push_back('|');
state.append("K8");    // A手牌
state.push_back('|');
state.push_back('2');  // B手牌(单个字符)
state.push_back('|');
state.append("7X");    // 桌面牌堆

生成的状态字符串:"1|K8|2|7X"

6. 使用无序集合实现状态判重与循环检测

1. 目标与建模

用哈希集合(unordered_set)进行游戏状态判重,通过检测重复状态来判定游戏进入无限循环,从而确保模拟算法的终止性。要求能正确实现基于集合的循环检测机制。

2. 核心实现方法

cpp 复制代码
unordered_set<string> seen;  // 全局状态集合

// 每轮生成状态字符串 state 后
auto result = seen.insert(state);  // 尝试插入集合
if (!result.second) {              // 插入失败,说明状态已存在
    // 检测到重复状态,游戏进入无限循环
    return -1;  // 或根据题目要求返回特定结果
}

insert() 返回值:pair<iterator, bool>

second 为 true:状态首次出现,成功插入

second 为 false:状态已存在,插入失败

为什么状态重复 = 无限循环?

游戏的演变是 "确定性" 的:给定一个完整状态(turn、A/B 手牌、桌面牌),下一步的操作(谁出牌、出什么牌、是否收牌、状态如何变化)是唯一确定的。因此如果某个状态第二次出现,说明从这个状态开始的所有后续步骤都会和第一次完全一样,形成 "闭环",永远无法结束。

7. 终止条件

终止条件定义

根据游戏规则,游戏结束的唯一条件是:某一方手牌为空。表现为:

玩家在出牌后手牌变为空

游戏立即结束,对方获胜

检查时机的关键原则

核心原则:只有在没有触发赢牌且准备切换回合时,才检查当前出牌方是否手牌为空。

错误检查的后果:如果在赢牌后立即检查,会将本该继续的局面误判为结束,因为:

赢牌玩家收回了牌,手牌必然非空

根据规则,赢牌玩家应继续出牌

此时检查 empty() 无意义且会导致逻辑错误

代码演变

Step 0:最小骨架

目标:确认输入输出格式无误。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

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

    string sA, sB;
    cin >> sA >> sB;

    // TODO: 模拟游戏
    cout << -1 << "\n";
    return 0;
}

Step 1:把手牌建成队列结构

变化:引入 deque<char> A,B,把字符串变成"队头出、队尾进"的手牌结构。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

string toStr(const deque<char>& d) {
    return string(d.begin(), d.end());
}

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

    string sA, sB;
    cin >> sA >> sB;

    deque<char> A(sA.begin(), sA.end()); 
    deque<char> B(sB.begin(), sB.end());

    // 先看看转回字符串是否正常
    // (后面真正输出胜者手牌也会用到)
    // cout << toStr(A) << "\n" << toStr(B) << "\n";

    cout << -1 << "\n";
    return 0;
}
复制代码

Step 2:加入桌面牌堆 + 轮流出牌框架

变化:

引入 vector<char> table 表示桌面(back() 是桌面最上面)。

引入 turn 控制轮到谁出牌。

先实现"轮流从队头出一张,压到桌面",暂时不处理赢牌规则。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

string toStr(const deque<char>& d) {
    return string(d.begin(), d.end());
}

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

    string sA, sB;
    cin >> sA >> sB;

    deque<char> A(sA.begin(), sA.end()); 
    deque<char> B(sB.begin(), sB.end());
    vector<char> table;

    int turn = 0; // 0:A出 1:B出

    while (!A.empty() && !B.empty()) {
        deque<char>& me = (turn == 0 ? A : B);

        char x = me.front(); 
        me.pop_front();

        table.push_back(x); // 压到桌面最上面

        // 暂不赢牌:直接换人
        turn ^= 1;
    }

    // 暂时还不会输出正确答案,先占位
    cout << -1 << "\n";
    return 0;
}
复制代码

Step 3:加入快速判断桌面是否已有该牌

变化:

用 pos[ch] 记录牌点 ch 在桌面中的下标;不在则 -1。

出牌时先读 old = pos[x],再把 pos[x] 更新为新位置。

仍然不做赢牌,只是把"能不能赢"的判断条件准备好。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

string toStr(const deque<char>& d) {
    return string(d.begin(), d.end());
}

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

    string sA, sB;
    cin >> sA >> sB;

    deque<char> A(sA.begin(), sA.end()); 
    deque<char> B(sB.begin(), sB.end());
    vector<char> table;

    int pos[128];
    fill(pos, pos + 128, -1);

    int turn = 0; // 0:A出 1:B出

    while (!A.empty() && !B.empty()) {
        deque<char>& me = (turn == 0 ? A : B);

        char x = me.front(); 
        me.pop_front();

        int old = pos[x]; // 出牌前是否在桌面出现过

        table.push_back(x);
        pos[x] = table.size() - 1;

        if (old == -1) {
            // 桌面没这张牌 -> 换人
            turn ^= 1;
        } else {
            // 桌面有这张牌 -> 下一步实现"收牌"
            // 先占位不做
        }
    }

    cout << -1 << "\n";
    return 0;
}
复制代码

Step 4:实现赢牌收回一段桌面牌

变化:当 old != -1 时:

赢牌方把桌面从顶端 table.back() 一直收回到 old(含)

收回顺序要与桌面相反,所以从 i=table.size()-1 递减到 old,逐张 push_back 到手牌队尾

同时把这些牌在 pos 中清掉(设回 -1)

table.resize(old) 截掉被收走的后缀

赢牌方继续出牌:turn 不变

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

string toStr(const deque<char>& d) {
    return string(d.begin(), d.end());
}

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

    string sA, sB;
    cin >> sA >> sB;

    deque<char> A(sA.begin(), sA.end()); 
    deque<char> B(sB.begin(), sB.end());
    vector<char> table;

    int pos[128];
    fill(pos, pos + 128, -1);

    int turn = 0; // 0:A出 1:B出

    while (!A.empty() && !B.empty()) {
        deque<char>& me = (turn == 0 ? A : B);

        char x = me.front(); 
        me.pop_front();
        int old = pos[x];

        table.push_back(x);
        pos[x] = table.size() - 1;

        if (old == -1) {
            // 没赢牌:换人
            turn ^= 1;
        } else {
            // 赢牌:收回桌面后缀 [old .. end)
            for (int i = table.size() - 1; i >= old; --i) {
                char t = table[i];
                me.push_back(t);
                pos[t] = -1;
            }
            table.resize(old);
            // 赢牌方继续:turn 不变
        }
    }

    cout << -1 << "\n";
    return 0;
}
复制代码

Step 5:补齐游戏结束条件和输出胜者手牌

题意关键句:当某一方出掉手里最后一张牌,但无法从桌面上赢取牌时,游戏立即结束。

变化:在"没赢牌(old==-1)且换人之后",如果 me 已空,则立即结束,输出对手手牌。

另外,循环外也处理一下正常结束(某人空了)

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

string toStr(const deque<char>& d) {
    return string(d.begin(), d.end());
}

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

    string sA, sB;
    cin >> sA >> sB;

    deque<char> A(sA.begin(), sA.end()); 
    deque<char> B(sB.begin(), sB.end());
    vector<char> table;

    int pos[128];
    fill(pos, pos + 128, -1);

    int turn = 0; // 0:A出 1:B出

    while (!A.empty() && !B.empty()) {
        deque<char>& me = (turn == 0 ? A : B);
        deque<char>& op = (turn == 0 ? B : A);

        char x = me.front(); 
        me.pop_front();
        int old = pos[x];

        table.push_back(x);
        pos[x] = table.size() - 1;

        if (old == -1) {
            // 没赢牌:换人
            turn ^= 1;

            // 若刚好打空且没赢牌:立刻结束,对手赢(桌面不归任何人)
            if (me.empty()) {
                cout << toStr(op) << "\n";
                return 0;
            }
        } else {
            // 赢牌:收回 [old..end)
            for (int i = table.size() - 1; i >= old; --i) {
                char t = table[i];
                me.push_back(t);
                pos[t] = -1;
            }
            table.resize(old);
        }
    }

    // 正常情况:谁没牌谁输,输出另一个
    cout << (A.empty() ? toStr(B) : toStr(A)) << "\n";
    return 0;
}

在这一步题目案例已经可以正确通过,下面的Step6思路更加严谨

Step 6:加入严格判环

变化:

用 unordered_set<string> seen 记录局面。

每轮开头把 (turn | A | B | table) 编成字符串 state,如果已出现则进入循环,输出 -1。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

string toStr(const deque<char>& d){
    return string(d.begin(), d.end());
}

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

    string sA, sB;
    cin >> sA >> sB;

    deque<char> A(sA.begin(), sA.end()); 
    deque<char> B(sB.begin(), sB.end());
    vector<char> table;
    int pos[128];
    fill(pos, pos + 128, -1);

    int turn = 0; // 0:A出 1:B出
    unordered_set<string> seen;

    while (true) {
        string state;
        state.push_back(char('0' + turn));
        state.push_back('|'); state += toStr(A);
        state.push_back('|'); state += toStr(B);
        state.push_back('|'); state.append(table.begin(), table.end());
        if (!seen.insert(state).second) { cout << -1 << "\n"; return 0; }

        deque<char> &me = (turn == 0 ? A : B);
        deque<char> &op = (turn == 0 ? B : A);

        char x = me.front(); 
        me.pop_front();
        int old = pos[x];

        table.push_back(x);
        pos[x] = table.size() - 1;

        if (old == -1) {
            turn ^= 1;
            if (me.empty()) { cout << toStr(op) << "\n"; return 0; }
        } else {
            for (int i = table.size() - 1; i >= old; --i) {
                char t = table[i];
                me.push_back(t);
                pos[t] = -1;
            }
            table.resize(old);
        }
    }
}
复制代码

简单解法

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

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

    string sA, sB;
    cin >> sA >> sB;
    
    deque<char> A(sA.begin(), sA.end());
    deque<char> B(sB.begin(), sB.end());
    vector<char> table;
    int turn = 0; // 0代表A
    
    for (int step = 0; step < 200000; ++step) {
        if (A.empty()) { cout << string(B.begin(), B.end()) << "\n"; return 0; }
        if (B.empty()) { cout << string(A.begin(), A.end()) << "\n"; return 0; }
        
        deque<char>& me = turn ? B : A;  
        char x = me.front();
        me.pop_front();
        table.push_back(x);
        
        // 搜索相同牌
        int k = -1;
        for (int i = table.size() - 2; i >= 0; --i) {
            if (table[i] == x) { k = i; break; }
        }
        
        if (k == -1) {
            turn ^= 1;  // 换人
        } else {
            // 收牌
            for (int i = table.size() - 1; i >= k; --i) {
                me.push_back(table[i]);
            }
            table.resize(k);
            // 赢牌继续,turn不变
        }
    }
    
    cout << -1 << "\n";
    return 0;
}

题目数据范围小(桌面牌 ≤ 100)可以选择这种思路

table.size() - 2 这里为什么减去2?

table.push_back(x); 已经将新牌x放入了table

现在 table 的状态:

0\] \[1\] ... \[table.size()-2\] \[table.size()-1

↑ 这是刚放的牌x

所以当我们要搜索相同牌时:

刚放入的牌在 table.size() - 1 位置

我们要搜索之前是否有相同的牌

应该从 table.size() - 2 开始搜索

相关推荐
w-w0w-w2 小时前
运算符重载
c++
持梦远方3 小时前
持梦行文本编辑器(cmyfEdit):架构设计与十大核心功能实现详解
开发语言·数据结构·c++·算法·microsoft·visual studio
小灰灰搞电子3 小时前
C++ 文件操作详解
开发语言·c++·文件操作
im_AMBER3 小时前
Leetcode 90 最佳观光组合
数据结构·c++·笔记·学习·算法·leetcode
Trouvaille ~3 小时前
【C++篇】智能指针详解(一):从问题到解决方案
开发语言·c++·c++11·类和对象·智能指针·raii
Wang15304 小时前
c++与Java谁的性能更胜一筹
java·c++
Tipriest_5 小时前
C++ 中 std::move 的使用方法与注意事项
c++·move
yuuki2332335 小时前
【C++】vector底层实现全解析
c++·后端·算法
小尧嵌入式5 小时前
C++选择排序插入排序希尔排序快排归并排及大小根堆实现优先级队列
数据结构·c++·windows·算法·排序算法