<?xml version="1.0" encoding="utf-8"?>
<search> 
  
  
    
    <entry>
      <title>Add(残差连接)</title>
      <link href="/2026/05/07/Add/"/>
      <url>/2026/05/07/Add/</url>
      
        <content type="html"><![CDATA[<p>Add(残差连接)，<strong>把“这一层的输入”和“这一层的输出”加起来，作为最终输出。</strong><br><img src="/../images/image-20260507233238099.png" alt="image-20260507233238099"></p>        <h2 id="Add做了什么"   >          <a href="#Add做了什么" class="heading-link"><i class="fas fa-link"></i></a><a href="#Add做了什么" class="headerlink" title="Add做了什么"></a>Add做了什么</h2>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#输出=输入＋F(输入)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">residual_block</span>(<span class="params">x</span>):</span><br><span class="line">    <span class="comment"># x: 这一层的输入</span></span><br><span class="line">    output = layer(x)  <span class="comment"># 对x做点什么（注意力、前馈等）</span></span><br><span class="line">    <span class="keyword">return</span> x + output  <span class="comment"># 加回去</span></span><br></pre></td></tr></table></div></figure><p>为什么要这么做呢，这样做首先保留了原始输入x，哪怕学习效果不好，也保留了原始x可以让你撤回。其次每一层只需要学习”增量”（输入和理想输出之间的差值），而不是从零学习完整输出。比如从5-&gt;5.1,只需要输出0.1即可，小量更容易学习。<br>综上：**Add提高了训练稳定性（容错）**和学习效率</p>        <h2 id="Add解决了什么"   >          <a href="#Add解决了什么" class="heading-link"><i class="fas fa-link"></i></a><a href="#Add解决了什么" class="headerlink" title="Add解决了什么"></a>Add解决了什么</h2>      <p><strong>缓解[[梯度消失]]：</strong> 在反向传播时，梯度可以直接通过残差路径（加号）无损地流回浅层网络，确保深层参数也能得到有效的更新信号。</p><p><strong>信息高速公路：</strong> 为模型提供了一条“捷径”，使得网络即使很深，浅层的信息也能相对容易地传递到深层，反之亦然。</p><p><strong>模型更容易优化：</strong> 让网络更容易学习到一个恒等映射（即输出等于输入），这通常是深层网络一个不错的起点。如果子层需要做出改变，它只需要学习相对于输入的“残差”（Residual）即可。</p>        <h2 id="Add在Transformer的应用"   >          <a href="#Add在Transformer的应用" class="heading-link"><i class="fas fa-link"></i></a><a href="#Add在Transformer的应用" class="headerlink" title="Add在Transformer的应用"></a>Add在Transformer的应用</h2>      ]]></content>
      
      
      <categories>
          
          <category> AI </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> Transformer </tag>
            
            <tag> AI </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>BatchNorm</title>
      <link href="/2026/05/07/BatchNorm/"/>
      <url>/2026/05/07/BatchNorm/</url>
      
        <content type="html"><![CDATA[<ul><li><strong>Batch Normalization（批量归一化）</strong> 是一种<strong>标准化技术</strong>，用于深度神经网络训练,尤其CV</li></ul>        <h2 id="Batch-Norm做了什么"   >          <a href="#Batch-Norm做了什么" class="heading-link"><i class="fas fa-link"></i></a><a href="#Batch-Norm做了什么" class="headerlink" title="Batch Norm做了什么"></a>Batch Norm做了什么</h2>      <p>对于一个批次里的多个样本，它们有相同的特征。但不同样本的同一个特征，数值范围可能差异很大。比如一个批次里有两个人，A年收入500万，B年收入5万。那么这两个样本传入网络时，年收入这个特征的数值范围波动剧烈，<strong>导致模型在批次之间来回调整，训练不稳定。</strong></p><p><strong>所以我们需要让同一个特征在不同样本之间的数值范围接近，对每个特征在批次维度上进行归一化</strong>，<strong>也就是让每个特征在当前批次上的均值为0、方差为1。</strong></p><blockquote><p>对比记忆：</p><ul><li><strong>LayerNorm</strong>：对一个样本的<strong>所有特征</strong>做归一化（行内归一化）</li><li><strong>BatchNorm</strong>：对一个批次内的<strong>同一个特征</strong>做归一化（列内归一化）</li></ul></blockquote>        <h2 id="BatchNorm解决了什么"   >          <a href="#BatchNorm解决了什么" class="heading-link"><i class="fas fa-link"></i></a><a href="#BatchNorm解决了什么" class="headerlink" title="BatchNorm解决了什么"></a>BatchNorm解决了什么</h2>      <p>它主要解决的是<strong>训练过程中的内部协变量偏移（ICS）</strong>，但视角和LayerNorm不同。</p>        <h3 id="1-内部协变量偏移"   >          <a href="#1-内部协变量偏移" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-内部协变量偏移" class="headerlink" title="1. 内部协变量偏移"></a>1. 内部协变量偏移</h3>      <p>首先你需要知道模型的训练过程：<br>前向传播 → 计算损失 → 反向传播 → 计算梯度 → 更新所有层的参数(W1,W2,W3…）</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 假设一个2层网络，批次大小为2</span></span><br><span class="line"><span class="comment"># 批次输入：两个样本</span></span><br><span class="line">x = [[<span class="number">1</span>, <span class="number">100</span>],   <span class="comment"># 样本1：特征1=1，特征2=100</span></span><br><span class="line">     [<span class="number">2</span>, <span class="number">50</span>]]    <span class="comment"># 样本2：特征1=2，特征2=50</span></span><br><span class="line"><span class="comment"># 第1步训练</span></span><br><span class="line">W1 = [[<span class="number">0.1</span>, <span class="number">0.2</span>]]  <span class="comment"># 初始权重</span></span><br><span class="line">h1 = x @ W1.T = [[<span class="number">0.1</span>*<span class="number">1</span>+<span class="number">0.2</span>*<span class="number">100</span>, <span class="number">0.1</span>*<span class="number">2</span>+<span class="number">0.2</span>*<span class="number">50</span>]] = [[<span class="number">20.1</span>, <span class="number">10.2</span>]]  <span class="comment"># 输出范围正常</span></span><br><span class="line"><span class="comment"># 计算损失，更新W1（假设梯度让W1变大）</span></span><br><span class="line">W1_new = [[<span class="number">0.5</span>, <span class="number">0.6</span>]]</span><br><span class="line">h1_new = x @ W1_new.T = [[<span class="number">0.5</span>*<span class="number">1</span>+<span class="number">0.6</span>*<span class="number">100</span>, <span class="number">0.5</span>*<span class="number">2</span>+<span class="number">0.6</span>*<span class="number">50</span>]] = [[<span class="number">60.5</span>, <span class="number">31.0</span>]]</span><br><span class="line"><span class="comment"># 第2层看到h1从[20.1, 10.2]变成[60.5, 31.0]</span></span><br><span class="line"><span class="comment"># 变化很大！而且两个样本的特征1和特征2之间的比例也变了</span></span><br><span class="line"><span class="comment"># 这就是BatchNorm要解决的第2层输入分布不稳定问题</span></span><br></pre></td></tr></table></div></figure><p>我们知道模型训练过程中，参数会不断更新，导致每一层的输入分布也在变化。如果同一个特征在不同样本之间数值范围波动太大（比如年收入这个特征，有的样本是5万，有的是500万），那么：</p><ul><li><strong>梯度计算会被大数值样本主导</strong>：年收入500万的那个样本，它的梯度会远远大于年收入5万的样本，模型只关注“有钱人”，忽略了“普通人”的模式。</li><li><strong>训练震荡</strong>：这个批次样本A（高收入）主导更新，下个批次样本B（低收入）主导更新，模型来回摇摆，难以收敛。</li></ul>        <h3 id="2-对学习率更友好"   >          <a href="#2-对学习率更友好" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-对学习率更友好" class="headerlink" title="2. 对学习率更友好"></a>2. 对学习率更友好</h3>      <p>没有BatchNorm时，你对学习率非常敏感：</p><ul><li>学习率稍大：遇到大数值样本，一步跨太远，崩了</li><li>学习率稍小：遇到小数值样本，几乎不动- <strong>Batch Normalization（批量归一化）</strong> 是一种<strong>标准化技术</strong>，用于深度神经网络训练<br>有了BatchNorm，每个特征的数值范围都被稳定在相似的尺度上，你可以用更大的学习率，训练更快更稳。</li></ul><blockquote><p>注意：BatchNorm主要解决的是<strong>批次内特征尺度不一致</strong>导致的训练不稳定，而不是直接解决梯度爆炸&#x2F;消失（虽然它能缓解）。梯度爆炸&#x2F;消失更多是网络深度和激活函数的问题。</p></blockquote>        <h2 id="BatchNorm的具体实现"   >          <a href="#BatchNorm的具体实现" class="heading-link"><i class="fas fa-link"></i></a><a href="#BatchNorm的具体实现" class="headerlink" title="BatchNorm的具体实现"></a>BatchNorm的具体实现</h2>      <p>前文提到，我们需要对<strong>每个特征</strong>在<strong>批次维度</strong>上进行归一化，也就是让这个特征在当前批次上的均值为0、方差为1。</p><p><strong>公式</strong>：  </p><p>其中：</p><ul><li><p><code>μ_B</code>：当前批次上，某个特征的平均值</p></li><li><p><code>σ_B^2</code>：当前批次上，某个特征的方差</p></li><li><p><code>γ</code>和<code>β</code>：可学习的缩放和平移参数（和LayerNorm一样）</p></li></ul>        <h3 id="举个例子"   >          <a href="#举个例子" class="heading-link"><i class="fas fa-link"></i></a><a href="#举个例子" class="headerlink" title="举个例子"></a>举个例子</h3>      <p>假设一个批次有2个样本，每个样本有3个特征（年龄、年收入、步数）：</p><p>text</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">批次数据：</span><br><span class="line">样本A: [25, 500000, 8000]</span><br><span class="line">样本B: [35, 300000, 6000]</span><br><span class="line"></span><br><span class="line">**对“年收入”这个特征进行BatchNorm**（其他特征同理）：</span><br><span class="line"></span><br><span class="line">1. 计算这一列的均值：μ = (500000 + 300000) / 2 = 400000</span><br><span class="line">    </span><br><span class="line">2. 计算这一列的方差：σ² = ((500000-400000)² + (300000-400000)²) / 2 = (100000² + (-100000)²) / 2 = 10^10</span><br><span class="line">    </span><br><span class="line">3. 标准差：σ = 100000</span><br><span class="line">    </span><br><span class="line">4. 归一化：</span><br><span class="line">    </span><br><span class="line">    - 样本A的年收入：(500000 - 400000) / 100000 = 1</span><br><span class="line">        </span><br><span class="line">    - 样本B的年收入：(300000 - 400000) / 100000 = -1</span><br><span class="line">        </span><br></pre></td></tr></table></div></figure><p><strong>经过BatchNorm处理后</strong>：</p><p>text</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">样本A: [年龄归一化后, 1, 步数归一化后]</span><br><span class="line">样本B: [年龄归一化后, -1, 步数归一化后]</span><br></pre></td></tr></table></div></figure><blockquote><p>γ和β同样是可学习参数。如果网络发现原始分布更好，可以把γ&#x3D;100000、β&#x3D;400000学回来（还原原始值）；如果某种中间分布更好，也可以调整。</p></blockquote>        <h3 id="和-LayerNorm-的对比"   >          <a href="#和-LayerNorm-的对比" class="heading-link"><i class="fas fa-link"></i></a><a href="#和-LayerNorm-的对比" class="headerlink" title="和[[LayerNorm]]的对比"></a>和[[LayerNorm]]的对比</h3>      <div class="table-container"><table><thead><tr><th>操作</th><th>对谁归一化</th><th>结果</th></tr></thead><tbody><tr><td><strong>LayerNorm</strong></td><td>对<strong>一个样本</strong>的所有特征</td><td>这个样本的3个特征之间范围接近</td></tr><tr><td><strong>BatchNorm</strong></td><td>对<strong>一个特征</strong>的所有样本</td><td>这个特征在不同样本之间范围接近</td></tr></tbody></table></div><p>用上面的例子：</p><ul><li><p><strong>LayerNorm后</strong>：样本A自己的年龄、收入、步数三个数范围接近（比如[-0.7, 1.4, -0.7]）</p></li><li><p><strong>BatchNorm后</strong>：样本A和样本B的收入这两个数范围接近（比如[1, -1]）</p></li></ul>        <h2 id="这样下来你得到了什么？"   >          <a href="#这样下来你得到了什么？" class="heading-link"><i class="fas fa-link"></i></a><a href="#这样下来你得到了什么？" class="headerlink" title="这样下来你得到了什么？"></a>这样下来你得到了什么？</h2>      <ol><li><strong>特征尺度统一</strong>：不同样本的同一个特征不再有量级差异。年收入500万和30万的人，在归一化后可能变成1和-0.5，处于同一数量级。<strong>高收入样本不再主导梯度。</strong></li><li><strong>训练更稳定</strong>：每个批次输入给下一层的分布都大致相同（均值0、方差1），参数更新不再被批次间的数值波动干扰。</li><li><strong>可以使用更大的学习率</strong>：因为数值范围被控制住了，不用担心一步踩空。</li><li><strong>有一定正则化效果</strong>：因为每个批次的均值和方差都有微小波动，相当于给训练引入了噪声，可以防止过拟合（这也是为什么BatchNorm层后面通常不需要再加Dropout的原因之一）。</li></ol>        <h2 id="一个关键的注意事项"   >          <a href="#一个关键的注意事项" class="heading-link"><i class="fas fa-link"></i></a><a href="#一个关键的注意事项" class="headerlink" title="一个关键的注意事项"></a>一个关键的注意事项</h2>      <p><strong>BatchNorm在训练和推理时的行为不同</strong>：</p><ul><li><strong>训练时</strong>：用当前批次的均值和方差</li><li><strong>推理时</strong>：用训练过程中所有批次的<strong>移动平均</strong>（running average），因为推理时可能只有一个样本，没法算批次统计量</li></ul><p>这是BatchNorm和LayerNorm的一个本质区别：LayerNorm不依赖批次大小，训练推理行为一致；BatchNorm依赖批次大小，且训练推理行为不同。</p>]]></content>
      
      
      <categories>
          
          <category> AI </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> Transformer </tag>
            
            <tag> AI </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>LayerNorm</title>
      <link href="/2026/05/07/LayerNorm/"/>
      <url>/2026/05/07/LayerNorm/</url>
      
        <content type="html"><![CDATA[<p>LayerNorm（层归一化），多用于NLP<br>![[Pasted image 20260507183851.png]]</p>        <h2 id="LayerNorm做了什么"   >          <a href="#LayerNorm做了什么" class="heading-link"><i class="fas fa-link"></i></a><a href="#LayerNorm做了什么" class="headerlink" title="LayerNorm做了什么"></a>LayerNorm做了什么</h2>      <p>对于一个样本的几个特征，也许他们的特征值分布太分散。比如一个人的年收入是10000000，但是他的身高体重是180cm和70kg。那么这个数据传递给下一个网络时，年收入的权重就会远远盖过身高体重等。<strong>让模型的训练只由某个特征主导。</strong><br><strong>所以我们需要让一个样本的特征值在数值范围上接近，对单个样本的所有特征进行归一化</strong>，<strong>也就是使其均值为0、方差为1。</strong></p>        <h2 id="LayNorm解决了什么"   >          <a href="#LayNorm解决了什么" class="heading-link"><i class="fas fa-link"></i></a><a href="#LayNorm解决了什么" class="headerlink" title="LayNorm解决了什么"></a>LayNorm解决了什么</h2>      <p>一般来说我们认为它解决了两个问题</p><ol><li><strong>-内部协变量偏移</strong><br> 名词听起来很抽象，首先你需要知道模型的训练过程。<br>  前向传播 → 计算损失 → 反向传播 → 计算梯度 → 更新所有层的参数(W1,W2,W3…）</li></ol><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 假设一个3层网络</span></span><br><span class="line">x = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]  <span class="comment"># 输入</span></span><br><span class="line"><span class="comment"># 第1步训练</span></span><br><span class="line">W1 = [[<span class="number">0.1</span>, <span class="number">0.2</span>, <span class="number">0.3</span>]]  <span class="comment"># 初始</span></span><br><span class="line">h1 = [<span class="number">0.1</span>*<span class="number">1</span>+<span class="number">0.2</span>*<span class="number">2</span>+<span class="number">0.3</span>*<span class="number">3</span>] = [<span class="number">1.4</span>]  <span class="comment"># 输出范围正常</span></span><br><span class="line"><span class="comment"># 计算损失，更新W1（假设梯度让W1变大）</span></span><br><span class="line">W1_new = [[<span class="number">0.5</span>, <span class="number">0.6</span>, <span class="number">0.7</span>]]</span><br><span class="line">h1_new = [<span class="number">0.5</span>*<span class="number">1</span>+<span class="number">0.6</span>*<span class="number">2</span>+<span class="number">0.7</span>*<span class="number">3</span>] = [<span class="number">0.5</span>+<span class="number">1.2</span>+<span class="number">2.1</span>] = [<span class="number">3.8</span>]  <span class="comment"># 范围变大</span></span><br><span class="line"><span class="comment"># 第2层看到h1从1.4变成3.8（变化很大！）</span></span><br><span class="line"><span class="comment"># 这就是ICS：第2层的输入分布变了，而且范围变散了</span></span><br><span class="line"><span class="comment"># 这种范围变大会影响第2层的梯度计算</span></span><br><span class="line"><span class="comment"># 导致第2层的参数W2更新指向错误方向</span></span><br><span class="line"><span class="comment"># 然后W2又会让第3层看到更分散的数据...</span></span><br><span class="line"><span class="comment"># 恶性循环</span></span><br></pre></td></tr></table></div></figure><pre><code>我们知道模型训练过程中是参数是会不断更新的，以此来变化下一层的输入。那么如果有一个数值过于大，大的纬度就会主导梯度，其他维度被忽略。并且更新时由于过大过小，模型需要猛踩刹车或者猛踩油门，也就是w的变化会忽大忽小而不能做出有效调整。</code></pre><ol start="2"><li><strong>梯度消失与梯度爆炸</strong><br> 前面提到，数据范围分散会导致更新时输出值过大过小，分别会导致梯度爆炸与消失<ul><li><strong>梯度爆炸</strong>：数值范围层层放大（例如每层放大10倍），传递到输出层时已达天文数字。反向传播时，这些巨大数值相乘，导致梯度超过 <code>float 32</code> 表示范围，变成 <code>inf</code>（无穷大）。模型瞬间崩坏，Loss 直接变成 <code>NaN</code>。这就是你说的“超范围”。</li><li><strong>梯度消失</strong>：数值范围层层缩小（例如每层缩小到 0.1 倍），传递到输出层时已接近 0。反向传播时，多次乘以小于 1 的数，梯度变成 <code>0</code>。模型再也学不到任何东西，Loss 永远不降。</li></ul></li></ol>        <h2 id="LayerNorm的具体实现"   >          <a href="#LayerNorm的具体实现" class="heading-link"><i class="fas fa-link"></i></a><a href="#LayerNorm的具体实现" class="headerlink" title="LayerNorm的具体实现"></a>LayerNorm的具体实现</h2>      <p>前文提到，我们需要对一个样本的每个特征进行归一化，也就是方差为1均值为0<br>公式：<br>![[Pasted image 20260507191827.png]]<br>例如一个样本如下：<strong>原始数据</strong>：<code>[25, 500000, 8000]</code><br>μ≈169341.67<br>σ≈233,760<br>归一化后的值&#x3D;x−μ&#x2F;σ<br><strong>经过 LayerNorm 处理后</strong>：<code>[-0.724, 1.415, -0.690]</code><br>（公式里的 γ 和 β 是两个可学习的参数。网络训练时可以调整它们。<br>比如，假设网络学习到 γ&#x3D;2,β&#x3D;0.5γ&#x3D;2,β&#x3D;0.5，那么最终输出就是：</p><ul><li>−0.724×2+0.5&#x3D;−0.948−0.724×2+0.5&#x3D;−0.948</li><li>1.415×2+0.5&#x3D;3.331.415×2+0.5&#x3D;3.33</li><li>−0.690×2+0.5&#x3D;−0.88−0.690×2+0.5&#x3D;−0.88<br>这样网络就有了灵活性：如果原始分布是最好的，它可以把 γ&#x3D;1,β&#x3D;0γ&#x3D;1,β&#x3D;0 学回来；如果另一种分布更好，它可以调整。）</li></ul><p>这样下来你得到了什么？</p><ol><li><strong>范围接近了</strong>：原来的 25 和 500000 相差 2 万倍，现在 -0.724 和 1.415 相差只有 2 倍左右。<strong>收入高的特征不再“欺负”其他特征了。</strong></li><li><strong>以0为中心</strong>：数据现在有正有负，大致分布在 -1 到 +1 之间。</li><li><strong>分布标准</strong>：这组新数据的均值是 0，标准差是 1。你可以快速验证一下：(−0.724+1.415−0.690)&#x2F;3≈0(−0.724+1.415−0.690)&#x2F;3≈0（均值0），离散程度也标准化了。</li></ol>        <h2 id="LayerNorm在Transformer里的运用"   >          <a href="#LayerNorm在Transformer里的运用" class="heading-link"><i class="fas fa-link"></i></a><a href="#LayerNorm在Transformer里的运用" class="headerlink" title="LayerNorm在Transformer里的运用"></a>LayerNorm在Transformer里的运用</h2>      <p>![[Pasted image 20260507193403.png|345]]<br>这是Transformer的解码器架构</p>        <h4 id="Add-Norm层"   >          <a href="#Add-Norm层" class="heading-link"><i class="fas fa-link"></i></a><a href="#Add-Norm层" class="headerlink" title="[[Add]] &amp; Norm层"></a><strong>[[Add]] &amp; Norm层</strong></h4>      <p>它实际上由两个独立的操作组成：<strong>残差连接（Add）</strong> 和 <strong>层归一化（Layer Normalization, Norm）</strong>。这两个操作协同工作，极大地提升了 Transformer 的训练稳定性、收敛速度和最终性能。<br>Norm 操作接收来自 Add 的输出（原始输入 + 子层变换）。这个组合信号的分布可能会剧烈变化，尤其是在训练初期。LN 将其“拉回”到一个相对稳定（均值为0，方差为1）的分布，极大地减少了训练的不稳定性，显著加快了收敛速度。γ 和 β 让模型能自适应地调整这个分布。</p>        <h6 id="2-2-与-BatchNorm-的对比"   >          <a href="#2-2-与-BatchNorm-的对比" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-2-与-BatchNorm-的对比" class="headerlink" title="2.2 与[[BatchNorm]]的对比"></a>2.2 与[[BatchNorm]]的对比</h6>      <div class="table-container"><table><thead><tr><th><strong>特性</strong></th><th><strong>BatchNorm</strong></th><th><strong>LayerNorm</strong></th></tr></thead><tbody><tr><td><strong>统计量计算</strong></td><td>沿批次维度（N）计算</td><td>沿特征维度（C&#x2F;H）计算</td></tr><tr><td><strong>依赖关系</strong></td><td>依赖批量大小</td><td>与批量大小无关</td></tr><tr><td><strong>适用场景</strong></td><td>CNN</td><td>RNN、Transformer</td></tr></tbody></table></div>]]></content>
      
      
      <categories>
          
          <category> AI </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> Transformer </tag>
            
            <tag> AI </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>梯度消失</title>
      <link href="/2026/05/07/%E6%A2%AF%E5%BA%A6%E6%B6%88%E5%A4%B1/"/>
      <url>/2026/05/07/%E6%A2%AF%E5%BA%A6%E6%B6%88%E5%A4%B1/</url>
      
        <content type="html"><![CDATA[        <h2 id="一、一句话定义"   >          <a href="#一、一句话定义" class="heading-link"><i class="fas fa-link"></i></a><a href="#一、一句话定义" class="headerlink" title="一、一句话定义"></a>一、一句话定义</h2>      <p><strong>梯度消失</strong>：反向传播时，梯度随着网络层数加深而<strong>指数级衰减</strong>，逐渐趋近于 0，导致浅层（靠近输入层）的参数几乎不更新，模型学不到底层的特征。</p><hr>        <h2 id="二、具体是怎样发生的？"   >          <a href="#二、具体是怎样发生的？" class="heading-link"><i class="fas fa-link"></i></a><a href="#二、具体是怎样发生的？" class="headerlink" title="二、具体是怎样发生的？"></a>二、具体是怎样发生的？</h2>              <h3 id="2-1-核心原因：也是连乘效应"   >          <a href="#2-1-核心原因：也是连乘效应" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-1-核心原因：也是连乘效应" class="headerlink" title="2.1 核心原因：也是连乘效应"></a>2.1 核心原因：也是连乘效应</h3>      <p>和梯度爆炸一样，梯度消失也是链式法则连乘的结果。区别在于：</p><ul><li><strong>梯度爆炸</strong>：乘数都 &gt; 1 → 越乘越大</li><li><strong>梯度消失</strong>：乘数都 &lt; 1 → 越乘越小</li></ul><p>python</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"># 一个3层网络的梯度传播（和前一讲相同的形式）</span><br><span class="line">∂loss/∂W₁ = ∂loss/∂h₃ · W₃ · ∂h₃/∂h₂ · W₂ · ∂h₂/∂h₁ · W₁ · ∂h₁/∂W₁</span><br><span class="line">              ↑                              ↑</span><br><span class="line">         从loss传来的初始梯度          每过一层就多乘一个数</span><br></pre></td></tr></table></div></figure><p><strong>如果每个乘数都小于 1，梯度就会指数级衰减到 0。</strong></p>        <h3 id="2-2-触发条件"   >          <a href="#2-2-触发条件" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-2-触发条件" class="headerlink" title="2.2 触发条件"></a>2.2 触发条件</h3>      <div class="table-container"><table><thead><tr><th align="left">条件</th><th align="left">说明</th><th align="left">示例</th></tr></thead><tbody><tr><td align="left"><strong>激活函数导数 &lt; 1</strong></td><td align="left">sigmoid 导数 ≤ 0.25，tanh 导数 ≤ 1</td><td align="left">sigmoid 饱和区导数接近 0</td></tr><tr><td align="left"><strong>权重值 &lt; 1</strong></td><td align="left">初始化太小或训练中权重变小</td><td align="left"><code>W = [[0.1, 0.2], [0.1, -0.2]]</code></td></tr><tr><td align="left"><strong>网络很深</strong></td><td align="left">层数越多，连乘次数越多</td><td align="left">10 层：0.25^10 ≈ 9.5e-7</td></tr><tr><td align="left"><strong>激活函数进入饱和区</strong></td><td align="left">输入太大或太小，sigmoid&#x2F;tanh 导数 ≈ 0</td><td align="left"><code>sigmoid(10) ≈ 1，导数 ≈ 0</code></td></tr></tbody></table></div>        <h3 id="2-3-数字演算（以-sigmoid-为例）"   >          <a href="#2-3-数字演算（以-sigmoid-为例）" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-3-数字演算（以-sigmoid-为例）" class="headerlink" title="2.3 数字演算（以 sigmoid 为例）"></a>2.3 数字演算（以 sigmoid 为例）</h3>      <p>python</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">sigmoid 函数特性：</span><br><span class="line">- 输出范围：(0, 1)</span><br><span class="line">- 最大值处导数：σ&#x27;(0) = 0.25</span><br><span class="line">- 饱和区（|x|&gt;5）导数：≈ 0.00...</span><br><span class="line"></span><br><span class="line">假设：</span><br><span class="line">- 每层激活函数的导数 ≈ 0.25（乐观估计）</span><br><span class="line">- 初始梯度（从 loss 传下来）= 1</span><br><span class="line"></span><br><span class="line">经过第 1 层后：梯度 = 1 × 0.25 = 0.25</span><br><span class="line">经过第 2 层后：梯度 = 0.25 × 0.25 = 0.0625</span><br><span class="line">经过第 3 层后：梯度 = 0.0625 × 0.25 = 0.015625</span><br><span class="line">...</span><br><span class="line">经过第 10 层后：梯度 = 1 × 0.25^10 ≈ 9.5 × 10⁻⁷（不到百万分之一）</span><br><span class="line">经过第 20 层后：梯度 = 1 × 0.25^20 ≈ 9.1 × 10⁻¹³（几乎为 0）</span><br><span class="line"></span><br><span class="line"># 指数衰减，同样可怕</span><br></pre></td></tr></table></div></figure><blockquote><p>注意：sigmoid 的实际导数往往小于 0.25（因为大多数输入不在 0 附近），所以实际衰减比这个例子更快。</p></blockquote><hr>        <h2 id="三、梯度消失会导致什么后果？"   >          <a href="#三、梯度消失会导致什么后果？" class="heading-link"><i class="fas fa-link"></i></a><a href="#三、梯度消失会导致什么后果？" class="headerlink" title="三、梯度消失会导致什么后果？"></a>三、梯度消失会导致什么后果？</h2>              <h3 id="3-1-浅层参数不更新"   >          <a href="#3-1-浅层参数不更新" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-1-浅层参数不更新" class="headerlink" title="3.1 浅层参数不更新"></a>3.1 浅层参数不更新</h3>      <p>python</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"># 以 10 层网络为例</span><br><span class="line">第 10 层（靠近输出）：梯度 ≈ 1    → 参数正常更新 ✓</span><br><span class="line">第 9 层：梯度 ≈ 0.25              → 参数更新变慢 ⚠️</span><br><span class="line">第 8 层：梯度 ≈ 0.0625            → 几乎不动 ⚠️</span><br><span class="line">第 7 层：梯度 ≈ 0.0156            → 基本不动 ❌</span><br><span class="line">第 6 层及以下：梯度 ≈ 0.000...    → 完全不动 ❌</span><br></pre></td></tr></table></div></figure>        <h3 id="3-2-模型“学不动”了"   >          <a href="#3-2-模型“学不动”了" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-2-模型“学不动”了" class="headerlink" title="3.2 模型“学不动”了"></a>3.2 模型“学不动”了</h3>      <ul><li><strong>深层（靠近输出）</strong>：勉强能学到一些东西，但因为没有浅层特征支撑，效果很差</li><li><strong>浅层（靠近输入）</strong>：几乎没被训练，仍然是随机初始化的状态</li><li><strong>整体效果</strong>：模型的 loss 下降极慢，或者卡在一个很高的值下不去</li></ul>        <h3 id="3-3-深层网络反而比浅层网络差"   >          <a href="#3-3-深层网络反而比浅层网络差" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-3-深层网络反而比浅层网络差" class="headerlink" title="3.3 深层网络反而比浅层网络差"></a>3.3 深层网络反而比浅层网络差</h3>      <p>这是最反直觉的现象：</p><p>python</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"># 现象</span><br><span class="line">20 层网络  &lt;  10 层网络  &lt;  5 层网络  （效果对比）</span><br><span class="line"></span><br><span class="line"># 原因</span><br><span class="line">不是过拟合，而是：20 层网络的浅层梯度已经消失了，有效层数可能只有 5 层左右</span><br><span class="line">其余 15 层是“僵尸层”——既没学到东西，还增加了噪声</span><br></pre></td></tr></table></div></figure><hr>        <h2 id="四、哪些场景特别容易发生梯度消失？"   >          <a href="#四、哪些场景特别容易发生梯度消失？" class="heading-link"><i class="fas fa-link"></i></a><a href="#四、哪些场景特别容易发生梯度消失？" class="headerlink" title="四、哪些场景特别容易发生梯度消失？"></a>四、哪些场景特别容易发生梯度消失？</h2>              <h3 id="4-1-使用-sigmoid-或-tanh-激活函数"   >          <a href="#4-1-使用-sigmoid-或-tanh-激活函数" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-1-使用-sigmoid-或-tanh-激活函数" class="headerlink" title="4.1 使用 sigmoid 或 tanh 激活函数"></a>4.1 使用 sigmoid 或 tanh 激活函数</h3>      <div class="table-container"><table><thead><tr><th align="left">激活函数</th><th align="left">导数范围</th><th align="left">最大导数</th><th align="left">风险</th></tr></thead><tbody><tr><td align="left"><strong>sigmoid</strong></td><td align="left">(0, 0.25]</td><td align="left">0.25</td><td align="left">🔴 极高</td></tr><tr><td align="left"><strong>tanh</strong></td><td align="left">(0, 1]</td><td align="left">1.0</td><td align="left">🟡 中等</td></tr><tr><td align="left"><strong>ReLU</strong></td><td align="left">{0, 1}</td><td align="left">1.0</td><td align="left">🟢 低</td></tr><tr><td align="left"><strong>LeakyReLU</strong></td><td align="left">{0.01, 1}</td><td align="left">1.0</td><td align="left">🟢 低</td></tr></tbody></table></div><blockquote><p>sigmoid 的导数最大值只有 0.25，连乘几层就消失了。这也是为什么现代深度学习几乎不用 sigmoid 作为隐藏层激活函数。</p></blockquote>        <h3 id="4-2-权重初始化太小"   >          <a href="#4-2-权重初始化太小" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-2-权重初始化太小" class="headerlink" title="4.2 权重初始化太小"></a>4.2 权重初始化太小</h3>      <p>python</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"># 错误的初始化方式</span><br><span class="line">W = torch.randn(512, 512) * 0.01   # 权重太小了！</span><br><span class="line"># 每层输出方差 ≈ 0.0001，激活函数输入极小</span><br><span class="line"># sigmoid(0.01) ≈ 0.5025，导数 ≈ 0.25（还好）</span><br><span class="line"># 但 tanh(0.01) ≈ 0.01，导数 ≈ 0.9999（较安全）</span><br></pre></td></tr></table></div></figure>        <h3 id="4-3-网络层数过深"   >          <a href="#4-3-网络层数过深" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-3-网络层数过深" class="headerlink" title="4.3 网络层数过深"></a>4.3 网络层数过深</h3>      <p>即使是 ReLU，没有残差连接的话，深层网络梯度消失风险也很大。因为：</p><ul><li>如果某层激活函数输出为 0（ReLU 死亡），梯度就断了</li><li>权重的随机性可能导致部分层有效梯度 &lt; 1</li></ul>        <h3 id="4-4-RNN-处理长序列"   >          <a href="#4-4-RNN-处理长序列" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-4-RNN-处理长序列" class="headerlink" title="4.4 RNN 处理长序列"></a>4.4 RNN 处理长序列</h3>      <p>RNN 的时间步展开和深度网络类似。</p><ul><li><strong>梯度消失</strong>：RNN 记不住很久以前的信息（LSTM 部分解决）</li><li><strong>梯度爆炸</strong>：RNN 在某个时间步突然崩溃（梯度裁剪解决）</li></ul><hr>        <h2 id="五、如何解决？（重点）"   >          <a href="#五、如何解决？（重点）" class="heading-link"><i class="fas fa-link"></i></a><a href="#五、如何解决？（重点）" class="headerlink" title="五、如何解决？（重点）"></a>五、如何解决？（重点）</h2>      <div class="table-container"><table><thead><tr><th align="left">方法</th><th align="left">原理</th><th align="left">一句话评价</th></tr></thead><tbody><tr><td align="left"><strong>ReLU &#x2F; 变体激活函数</strong></td><td align="left">正区间导数为 1，不衰减梯度</td><td align="left">🥇 最关键、最有效的改进</td></tr><tr><td align="left"><strong>残差连接</strong></td><td align="left">梯度有一条“高速公路”直通浅层</td><td align="left">🥇 Transformer 等架构的基础</td></tr><tr><td align="left"><strong>LayerNorm &#x2F; BatchNorm</strong></td><td align="left">稳定输入分布，防止进入饱和区</td><td align="left">🥈 间接但很重要</td></tr><tr><td align="left"><strong>合理初始化</strong></td><td align="left">让每层输出的方差保持为 1</td><td align="left">🥈 治本，从源头防止</td></tr><tr><td align="left"><strong>LSTM &#x2F; GRU</strong></td><td align="left">门控机制让梯度可以长时间保持</td><td align="left">🥇 RNN 场景的最佳方案</td></tr></tbody></table></div>        <h3 id="5-1-使用-ReLU-及其变体（最关键）"   >          <a href="#5-1-使用-ReLU-及其变体（最关键）" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-1-使用-ReLU-及其变体（最关键）" class="headerlink" title="5.1 使用 ReLU 及其变体（最关键）"></a>5.1 使用 ReLU 及其变体（最关键）</h3>      <p>python</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"># ReLU：最简单、最常用</span><br><span class="line">def relu(x):</span><br><span class="line">    return max(0, x)</span><br><span class="line"># 导数为 1（当 x &gt; 0）或 0（当 x &lt; 0）</span><br><span class="line"># 正区间梯度不衰减！</span><br><span class="line"></span><br><span class="line"># 变体：LeakyReLU（解决了 ReLU 死亡问题）</span><br><span class="line">def leaky_relu(x, alpha=0.01):</span><br><span class="line">    return max(alpha * x, x)</span><br><span class="line"># 负区间也有小梯度，神经元不会“死亡”</span><br><span class="line"></span><br><span class="line"># 变体：ELU / GELU / Swish（各有优缺点）</span><br></pre></td></tr></table></div></figure><p><strong>ReLU 带来的问题</strong>：</p><ul><li><strong>ReLU 死亡</strong>：如果输入始终为负，神经元输出恒为 0，梯度为 0，永远无法复活</li><li>解决方案：LeakyReLU、ELU、或更小的学习率 + 合理的初始化</li></ul>        <h3 id="5-2-残差连接（Add）"   >          <a href="#5-2-残差连接（Add）" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-2-残差连接（Add）" class="headerlink" title="5.2 残差连接（Add）"></a>5.2 残差连接（Add）</h3>      <p><strong>原理</strong>：让梯度有一条不经过任何权重乘法的直通路径。</p><p>python</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"># 残差块</span><br><span class="line">def residual_block(x):</span><br><span class="line">    output = layer(x)      # 对 x 做变换</span><br><span class="line">    return x + output      # 输出 = 输入 + 变换</span><br></pre></td></tr></table></div></figure><p><strong>梯度传播时</strong>：</p><p>text</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">∂loss/∂x = ∂loss/∂output × ∂output/∂x</span><br><span class="line">         = ∂loss/∂output × (1 + ∂layer/∂x)</span><br><span class="line">         = ∂loss/∂output + ∂loss/∂output × ∂layer/∂x</span><br><span class="line">                       ↑</span><br><span class="line">                这条路径不经过 layer 的权重！</span><br><span class="line">                梯度可以直接从 output 传到 x</span><br></pre></td></tr></table></div></figure><p><strong>效果</strong>：即使 <code>∂layer/∂x</code> 的梯度消失为 0，<code>∂loss/∂x</code> 仍然有 <code>∂loss/∂output</code>，不会消失。</p>        <h3 id="5-3-使用-LayerNorm-BatchNorm"   >          <a href="#5-3-使用-LayerNorm-BatchNorm" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-3-使用-LayerNorm-BatchNorm" class="headerlink" title="5.3 使用 LayerNorm &#x2F; BatchNorm"></a>5.3 使用 LayerNorm &#x2F; BatchNorm</h3>      <p><strong>原理</strong>：把激活函数的输入稳定在非饱和区（比如均值 0、方差 1 附近），让导数保持在较大值。</p><p>python</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"># 以 sigmoid 为例</span><br><span class="line">没有归一化时：x 可能很大（比如 10）→ sigmoid(10)≈1 → 导数≈0</span><br><span class="line">有归一化后：x 被拉回 0 附近 → sigmoid(0)=0.5 → 导数≈0.25</span><br></pre></td></tr></table></div></figure>        <h3 id="5-4-合理的权重初始化（Xavier-Kaiming）"   >          <a href="#5-4-合理的权重初始化（Xavier-Kaiming）" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-4-合理的权重初始化（Xavier-Kaiming）" class="headerlink" title="5.4 合理的权重初始化（Xavier &#x2F; Kaiming）"></a>5.4 合理的权重初始化（Xavier &#x2F; Kaiming）</h3>      <p><strong>原理</strong>：让每层的输出方差保持为 1，输入信号不衰减。</p><p>python</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"># Xavier 初始化（适合 tanh / sigmoid）</span><br><span class="line">nn.init.xavier_uniform_(W)</span><br><span class="line"># 让 Var(output) = Var(input)</span><br><span class="line"></span><br><span class="line"># Kaiming 初始化（适合 ReLU）</span><br><span class="line">nn.init.kaiming_uniform_(W, nonlinearity=&#x27;relu&#x27;)</span><br><span class="line"># 专门针对 ReLU 设计，考虑了 ReLU 会砍掉一半神经元</span><br></pre></td></tr></table></div></figure>        <h3 id="5-5-使用-LSTM-GRU（RNN-专用）"   >          <a href="#5-5-使用-LSTM-GRU（RNN-专用）" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-5-使用-LSTM-GRU（RNN-专用）" class="headerlink" title="5.5 使用 LSTM &#x2F; GRU（RNN 专用）"></a>5.5 使用 LSTM &#x2F; GRU（RNN 专用）</h3>      <p><strong>原理</strong>：引入门控机制（遗忘门、输入门、输出门），让梯度可以选择性地通过，不会在每个时间步都衰减。</p><p>python</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"># LSTM 的核心思想</span><br><span class="line"># 有一条“细胞状态”高速公路，梯度可以在上面长时间保持</span><br><span class="line">c_t = f_t * c_&#123;t-1&#125; + i_t * g_t</span><br><span class="line"># f_t 是遗忘门（0~1），控制多少旧信息保留</span><br><span class="line"># 如果 f_t 接近 1，梯度几乎不衰减</span><br></pre></td></tr></table></div></figure><hr>        <h2 id="六、如何判断发生了梯度消失？"   >          <a href="#六、如何判断发生了梯度消失？" class="heading-link"><i class="fas fa-link"></i></a><a href="#六、如何判断发生了梯度消失？" class="headerlink" title="六、如何判断发生了梯度消失？"></a>六、如何判断发生了梯度消失？</h2>              <h3 id="6-1-明显的信号"   >          <a href="#6-1-明显的信号" class="heading-link"><i class="fas fa-link"></i></a><a href="#6-1-明显的信号" class="headerlink" title="6.1 明显的信号"></a>6.1 明显的信号</h3>      <div class="table-container"><table><thead><tr><th align="left">现象</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left"><strong>Loss 下降极慢</strong></td><td align="left">训练了很久，loss 还是很高</td></tr><tr><td align="left"><strong>浅层参数几乎不变</strong></td><td align="left">打印浅层权重的变化，几乎为 0</td></tr><tr><td align="left"><strong>梯度值极小</strong></td><td align="left">浅层梯度在 1e-6 以下，甚至为 0</td></tr><tr><td align="left"><strong>深层效果好，浅层效果差</strong></td><td align="left">靠近输出的层学到了一些东西，但整体模型很差</td></tr><tr><td align="left"><strong>模型不收敛</strong></td><td align="left">loss 卡在一个值，怎么训练都不降</td></tr></tbody></table></div>        <h3 id="6-2-监控代码"   >          <a href="#6-2-监控代码" class="heading-link"><i class="fas fa-link"></i></a><a href="#6-2-监控代码" class="headerlink" title="6.2 监控代码"></a>6.2 监控代码</h3>      <p>python</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 训练循环中监控各层梯度的分布</span></span><br><span class="line"><span class="keyword">for</span> name, param <span class="keyword">in</span> model.named_parameters():</span><br><span class="line">    <span class="keyword">if</span> param.grad <span class="keyword">is</span> <span class="keyword">not</span> <span class="literal">None</span>:</span><br><span class="line">        grad_mean = param.grad.mean().item()</span><br><span class="line">        grad_std = param.grad.std().item()</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;name&#125;</span>: mean=<span class="subst">&#123;grad_mean:<span class="number">.2</span>e&#125;</span>, std=<span class="subst">&#123;grad_std:<span class="number">.2</span>e&#125;</span>&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 观察规律：</span></span><br><span class="line"><span class="comment"># 正常情况：浅层和深层的梯度量级相近</span></span><br><span class="line"><span class="comment"># 梯度消失：深层梯度 1e-3，浅层梯度 1e-8（差了 5 个数量级）</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 也可以可视化</span></span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"></span><br><span class="line">gradients = [p.grad.norm().item() <span class="keyword">for</span> p <span class="keyword">in</span> model.parameters()]</span><br><span class="line">plt.plot(gradients)</span><br><span class="line">plt.yscale(<span class="string">&#x27;log&#x27;</span>)  <span class="comment"># 对数坐标，更容易看出衰减趋势</span></span><br><span class="line">plt.title(<span class="string">&#x27;梯度范数分布（左：浅层，右：深层）&#x27;</span>)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></div></figure><hr>        <h2 id="七、梯度消失-vs-梯度爆炸：对比总结"   >          <a href="#七、梯度消失-vs-梯度爆炸：对比总结" class="heading-link"><i class="fas fa-link"></i></a><a href="#七、梯度消失-vs-梯度爆炸：对比总结" class="headerlink" title="七、梯度消失 vs 梯度爆炸：对比总结"></a>七、梯度消失 vs 梯度爆炸：对比总结</h2>      <div class="table-container"><table><thead><tr><th align="left">维度</th><th align="left">梯度消失</th><th align="left">梯度爆炸</th></tr></thead><tbody><tr><td align="left"><strong>现象</strong></td><td align="left">梯度 → 0</td><td align="left">梯度 → ∞</td></tr><tr><td align="left"><strong>原因</strong></td><td align="left">乘数 &lt; 1 连乘</td><td align="left">乘数 &gt; 1 连乘</td></tr><tr><td align="left"><strong>后果</strong></td><td align="left">浅层学不动，模型欠拟合</td><td align="left">Loss 变 NaN，模型崩溃</td></tr><tr><td align="left"><strong>发生概率</strong></td><td align="left">更常见</td><td align="left">相对少见</td></tr><tr><td align="left"><strong>主要元凶</strong></td><td align="left">sigmoid&#x2F;tanh 的导数 &lt; 1</td><td align="left">权重初始化太大</td></tr><tr><td align="left"><strong>高发场景</strong></td><td align="left">深层网络、RNN</td><td align="left">RNN、初始化不当</td></tr><tr><td align="left"><strong>直接解法</strong></td><td align="left">用 ReLU</td><td align="left">梯度裁剪</td></tr><tr><td align="left"><strong>治本解法</strong></td><td align="left">残差连接 + 归一化</td><td align="left">合理初始化 + 归一化</td></tr></tbody></table></div>]]></content>
      
      
      <categories>
          
          <category> AI </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> Transformer </tag>
            
            <tag> AI </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>梯度爆炸</title>
      <link href="/2026/05/07/%E6%A2%AF%E5%BA%A6%E7%88%86%E7%82%B8/"/>
      <url>/2026/05/07/%E6%A2%AF%E5%BA%A6%E7%88%86%E7%82%B8/</url>
      
        <content type="html"><![CDATA[        <h2 id="一、一句话定义"   >          <a href="#一、一句话定义" class="heading-link"><i class="fas fa-link"></i></a><a href="#一、一句话定义" class="headerlink" title="一、一句话定义"></a>一、一句话定义</h2>      <p><strong>梯度爆炸</strong>：反向传播时，梯度随着网络层数加深而<strong>指数级增长</strong>，变成天文数字（如 <code>10^8</code> 甚至 <code>inf</code>），导致参数更新步长巨大，模型直接崩溃。</p><hr>        <h2 id="二、具体是怎样发生的？"   >          <a href="#二、具体是怎样发生的？" class="heading-link"><i class="fas fa-link"></i></a><a href="#二、具体是怎样发生的？" class="headerlink" title="二、具体是怎样发生的？"></a>二、具体是怎样发生的？</h2>              <h3 id="2-1-核心原因：连乘效应"   >          <a href="#2-1-核心原因：连乘效应" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-1-核心原因：连乘效应" class="headerlink" title="2.1 核心原因：连乘效应"></a>2.1 核心原因：连乘效应</h3>      <p>反向传播时，梯度从输出层往输入层传播，<strong>每经过一层都要乘以该层权重的某种组合</strong>。如果这些乘数都大于1，梯度就会指数级膨胀。</p><p>python</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"># 一个3层网络的梯度传播（简化示意）</span><br><span class="line">∂loss/∂W₁ = ∂loss/∂h₃ · W₃ · ∂h₃/∂h₂ · W₂ · ∂h₂/∂h₁ · W₁ · ∂h₁/∂W₁</span><br><span class="line">              ↑                              ↑</span><br><span class="line">         从loss传来的初始梯度          每过一层就多乘一个W</span><br></pre></td></tr></table></div></figure>        <h3 id="2-2-触发条件"   >          <a href="#2-2-触发条件" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-2-触发条件" class="headerlink" title="2.2 触发条件"></a>2.2 触发条件</h3>      <div class="table-container"><table><thead><tr><th align="left">条件</th><th align="left">说明</th><th align="left">示例</th></tr></thead><tbody><tr><td align="left"><strong>权重值 &gt; 1</strong></td><td align="left">初始化或训练中权重变得较大</td><td align="left"><code>W = [[2.0, 1.5], [1.5, 2.0]]</code></td></tr><tr><td align="left"><strong>没有饱和激活函数</strong></td><td align="left">ReLU在正区间导数为1，不会压制梯度</td><td align="left"><code>ReLU(x) = max(0,x)</code> 导数恒为1</td></tr><tr><td align="left"><strong>网络很深</strong></td><td align="left">层数越多，连乘次数越多</td><td align="left">10层：2^10&#x3D;1024倍放大</td></tr><tr><td align="left"><strong>重复使用权重</strong></td><td align="left">RNN在同一权重上循环乘多次</td><td align="left">时间步100步 &#x3D; 乘100次</td></tr></tbody></table></div>        <h3 id="2-3-数字演算"   >          <a href="#2-3-数字演算" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-3-数字演算" class="headerlink" title="2.3 数字演算"></a>2.3 数字演算</h3>      <p>python</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">假设：</span><br><span class="line">- 每层权重的“尺度”约为 2</span><br><span class="line">- 激活函数用 ReLU（导数恒为 1）</span><br><span class="line">- 初始梯度（从 loss 传下来）= 1</span><br><span class="line"></span><br><span class="line">经过第 1 层后：梯度 = 1 × 2 = 2</span><br><span class="line">经过第 2 层后：梯度 = 2 × 2 = 4</span><br><span class="line">经过第 3 层后：梯度 = 4 × 2 = 8</span><br><span class="line">...</span><br><span class="line">经过第 10 层后：梯度 = 1 × 2^10 = 1024</span><br><span class="line">经过第 20 层后：梯度 = 1 × 2^20 ≈ 1,048,576（百万级）</span><br><span class="line">经过第 30 层后：梯度 = 1 × 2^30 ≈ 1,073,741,824（十亿级）</span><br><span class="line"></span><br><span class="line"># 指数增长，非常可怕</span><br></pre></td></tr></table></div></figure><hr>        <h2 id="三、梯度爆炸会导致什么后果？"   >          <a href="#三、梯度爆炸会导致什么后果？" class="heading-link"><i class="fas fa-link"></i></a><a href="#三、梯度爆炸会导致什么后果？" class="headerlink" title="三、梯度爆炸会导致什么后果？"></a>三、梯度爆炸会导致什么后果？</h2>              <h3 id="3-1-参数变成-NaN"   >          <a href="#3-1-参数变成-NaN" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-1-参数变成-NaN" class="headerlink" title="3.1 参数变成 NaN"></a>3.1 参数变成 NaN</h3>      <p>python</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"># 正常的参数更新公式</span><br><span class="line">w_new = w_old - learning_rate × gradient</span><br><span class="line"></span><br><span class="line"># 假设 gradient = 1e9，learning_rate = 0.001</span><br><span class="line"># 更新步长 = 1e9 × 0.001 = 1e6</span><br><span class="line"># w_old 原本可能是 0.5，一步之后变成 1000000.5</span><br><span class="line"># 下一轮前向传播，w × x 直接爆掉</span><br></pre></td></tr></table></div></figure>        <h3 id="3-2-Loss-变成-NaN（Not-a-Number）"   >          <a href="#3-2-Loss-变成-NaN（Not-a-Number）" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-2-Loss-变成-NaN（Not-a-Number）" class="headerlink" title="3.2 Loss 变成 NaN（Not a Number）"></a>3.2 Loss 变成 NaN（Not a Number）</h3>      <p>因为参数数值巨大，前向传播时计算的中间值也会巨大。一旦超过浮点数表示范围（<code>float32</code> 上限约 <code>3.4e38</code>），就会变成 <code>inf</code>（无穷大）。<code>inf</code> 参与任何运算，结果都是 <code>NaN</code>。</p>        <h3 id="3-3-模型无法恢复"   >          <a href="#3-3-模型无法恢复" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-3-模型无法恢复" class="headerlink" title="3.3 模型无法恢复"></a>3.3 模型无法恢复</h3>      <p>一旦参数中出现 <code>NaN</code>，后续所有计算都是 <code>NaN</code>。模型永远回不到正常状态，训练必须<strong>中断并从头重启</strong>。</p><hr>        <h2 id="四、哪些场景特别容易发生梯度爆炸？"   >          <a href="#四、哪些场景特别容易发生梯度爆炸？" class="heading-link"><i class="fas fa-link"></i></a><a href="#四、哪些场景特别容易发生梯度爆炸？" class="headerlink" title="四、哪些场景特别容易发生梯度爆炸？"></a>四、哪些场景特别容易发生梯度爆炸？</h2>              <h3 id="4-1-RNN-LSTM-处理长序列"   >          <a href="#4-1-RNN-LSTM-处理长序列" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-1-RNN-LSTM-处理长序列" class="headerlink" title="4.1 RNN &#x2F; LSTM 处理长序列"></a>4.1 RNN &#x2F; LSTM 处理长序列</h3>      <p>RNN 在每个时间步使用<strong>同一个权重矩阵</strong>。如果这个矩阵的特征值大于 1，梯度经过 100 个时间步的反向传播，就会被放大 100 次方倍。</p><p>python</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"># RNN 的循环结构</span><br><span class="line">h_t = tanh(W_h @ h_&#123;t-1&#125; + W_x @ x_t)</span><br><span class="line"># 梯度从第100步传回第1步，需要乘100次 W_h</span><br><span class="line"># 如果 W_h 的特征值 &gt; 1 → 爆炸</span><br></pre></td></tr></table></div></figure><blockquote><p>这也是为什么后来有了 LSTM 和 GRU——它们用门控机制来缓解这个问题。</p></blockquote>        <h3 id="4-2-初始化权重过大"   >          <a href="#4-2-初始化权重过大" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-2-初始化权重过大" class="headerlink" title="4.2 初始化权重过大"></a>4.2 初始化权重过大</h3>      <p>python</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"># 错误的初始化方式</span><br><span class="line">W = torch.randn(512, 512) * 2   # 均值为0，标准差为2</span><br><span class="line"># 每层输出范围放大2倍，梯度也随层数指数放大</span><br></pre></td></tr></table></div></figure>        <h3 id="4-3-层数过深且没有保护机制"   >          <a href="#4-3-层数过深且没有保护机制" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-3-层数过深且没有保护机制" class="headerlink" title="4.3 层数过深且没有保护机制"></a>4.3 层数过深且没有保护机制</h3>      <p>Transformer 有 12~24 层，如果不用残差连接和层归一化，梯度爆炸风险很高。</p><hr>        <h2 id="五、如何解决？（重点）"   >          <a href="#五、如何解决？（重点）" class="heading-link"><i class="fas fa-link"></i></a><a href="#五、如何解决？（重点）" class="headerlink" title="五、如何解决？（重点）"></a>五、如何解决？（重点）</h2>      <div class="table-container"><table><thead><tr><th align="left">方法</th><th align="left">原理</th><th align="left">一句话评价</th></tr></thead><tbody><tr><td align="left"><strong>梯度裁剪</strong></td><td align="left">限制梯度的最大值</td><td align="left">最直接、最常用、几乎零成本</td></tr><tr><td align="left"><strong>合理初始化</strong></td><td align="left">让权重尺度 ≈ 1&#x2F;√fan_in</td><td align="left">治本，从源头防止</td></tr><tr><td align="left"><strong>LayerNorm&#x2F;BatchNorm</strong></td><td align="left">稳定每层数值范围</td><td align="left">间接防止，顺便解决其他问题</td></tr><tr><td align="left"><strong>残差连接</strong></td><td align="left">梯度有一条“高速公路”</td><td align="left">让梯度可以不经过权重乘法</td></tr><tr><td align="left"><strong>降低学习率</strong></td><td align="left">减小更新步长</td><td align="left">治标不治本，但有帮助</td></tr></tbody></table></div>        <h3 id="5-1-梯度裁剪（最推荐）"   >          <a href="#5-1-梯度裁剪（最推荐）" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-1-梯度裁剪（最推荐）" class="headerlink" title="5.1 梯度裁剪（最推荐）"></a>5.1 梯度裁剪（最推荐）</h3>      <p><strong>原理</strong>：计算所有梯度的整体范数（可以理解为“梯度的总长度”），如果超过设定阈值，就按比例缩小，但<strong>保持方向不变</strong>。</p><p>python</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"># PyTorch 中的用法（只需一行代码）</span><br><span class="line">torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)</span><br><span class="line"></span><br><span class="line"># 具体效果演示</span><br><span class="line">原始梯度 = [0.5, 100, 0.3, 500]</span><br><span class="line">计算整体范数 ≈ sqrt(0.5² + 100² + 0.3² + 500²) ≈ 506</span><br><span class="line"></span><br><span class="line">max_norm = 1.0</span><br><span class="line">缩放因子 = 1.0 / 506 ≈ 0.002</span><br><span class="line"></span><br><span class="line">裁剪后 ≈ [0.001, 0.198, 0.0006, 0.988]</span><br><span class="line"># 方向没变（比例关系保留），但整体大小被限制在1以内</span><br></pre></td></tr></table></div></figure><p><strong>优点</strong>：</p><ul><li>直接有效，99% 的情况下能解决爆炸</li><li>计算成本极低（只多一步范数计算）</li><li>对训练速度影响微乎其微</li></ul><p><strong>缺点</strong>：</p><ul><li>只是“压在合理范围”，没有解决爆炸的根源</li></ul>        <h3 id="5-2-合理的权重初始化"   >          <a href="#5-2-合理的权重初始化" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-2-合理的权重初始化" class="headerlink" title="5.2 合理的权重初始化"></a>5.2 合理的权重初始化</h3>      <p><strong>原理</strong>：让每层输出的方差保持为 1，避免信号和梯度指数放大。</p><p>python</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"># Xavier / Glorot 初始化（适合 tanh / sigmoid）</span><br><span class="line">nn.init.xavier_uniform_(W)</span><br><span class="line"></span><br><span class="line"># Kaiming / He 初始化（适合 ReLU）</span><br><span class="line">nn.init.kaiming_uniform_(W, nonlinearity=&#x27;relu&#x27;)</span><br></pre></td></tr></table></div></figure><p><strong>效果</strong>：权重尺度约在 <code>1 / √fan_in</code> 左右，不会显著大于 1。</p>        <h3 id="5-3-使用归一化层"   >          <a href="#5-3-使用归一化层" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-3-使用归一化层" class="headerlink" title="5.3 使用归一化层"></a>5.3 使用归一化层</h3>      <p>LayerNorm（Transformer 用）和 BatchNorm（CNN 用）通过稳定每一层的数值范围，间接防止梯度爆炸。</p>        <h3 id="5-4-使用残差连接"   >          <a href="#5-4-使用残差连接" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-4-使用残差连接" class="headerlink" title="5.4 使用残差连接"></a>5.4 使用残差连接</h3>      <p>残差连接 <code>output = x + F(x)</code> 让梯度有一条<strong>直通路径</strong>：<code>∂loss/∂x</code> 可以直接从输出传到输入，不经过任何权重矩阵乘法。这条路径上的梯度不会爆炸。</p><hr>        <h2 id="六、如何判断发生了梯度爆炸？"   >          <a href="#六、如何判断发生了梯度爆炸？" class="heading-link"><i class="fas fa-link"></i></a><a href="#六、如何判断发生了梯度爆炸？" class="headerlink" title="六、如何判断发生了梯度爆炸？"></a>六、如何判断发生了梯度爆炸？</h2>              <h3 id="6-1-明显的信号"   >          <a href="#6-1-明显的信号" class="heading-link"><i class="fas fa-link"></i></a><a href="#6-1-明显的信号" class="headerlink" title="6.1 明显的信号"></a>6.1 明显的信号</h3>      <div class="table-container"><table><thead><tr><th align="left">现象</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">Loss 突然变成 <code>NaN</code></td><td align="left">最明显的信号，一眼就能看出来</td></tr><tr><td align="left">Loss 在某一步突然飙升</td><td align="left">比如从 2.3 跳到 1e8，然后变 NaN</td></tr><tr><td align="left">模型参数出现 <code>inf</code></td><td align="left"><code>print(param)</code> 能看到 <code>inf</code></td></tr><tr><td align="left">梯度值巨大</td><td align="left">正常梯度范数在 0.1~10 之间，爆炸时可达 1e6 以上</td></tr></tbody></table></div>        <h3 id="6-2-监控代码"   >          <a href="#6-2-监控代码" class="heading-link"><i class="fas fa-link"></i></a><a href="#6-2-监控代码" class="headerlink" title="6.2 监控代码"></a>6.2 监控代码</h3>      <p>python</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"># 训练循环中加入梯度监控</span><br><span class="line">for name, param in model.named_parameters():</span><br><span class="line">    if param.grad is not None:</span><br><span class="line">        grad_norm = param.grad.norm().item()</span><br><span class="line">        if grad_norm &gt; 100:</span><br><span class="line">            print(f&quot;⚠️ 梯度爆炸警告！&#123;name&#125;: &#123;grad_norm&#125;&quot;)</span><br><span class="line">        elif grad_norm &gt; 10:</span><br><span class="line">            print(f&quot;🔔 梯度偏大：&#123;name&#125;: &#123;grad_norm&#125;&quot;)</span><br><span class="line"></span><br><span class="line"># 或者监控整体梯度范数</span><br><span class="line">total_norm = 0</span><br><span class="line">for p in model.parameters():</span><br><span class="line">    if p.grad is not None:</span><br><span class="line">        total_norm += p.grad.norm().item() ** 2</span><br><span class="line">total_norm = total_norm ** 0.5</span><br><span class="line">print(f&quot;全局梯度范数: &#123;total_norm&#125;&quot;)  # 正常 &lt;10，爆炸时 &gt;1000</span><br></pre></td></tr></table></div></figure><hr>        <h2 id="七、总结：一张表说清楚"   >          <a href="#七、总结：一张表说清楚" class="heading-link"><i class="fas fa-link"></i></a><a href="#七、总结：一张表说清楚" class="headerlink" title="七、总结：一张表说清楚"></a>七、总结：一张表说清楚</h2>      <div class="table-container"><table><thead><tr><th align="left">问题</th><th align="left">答案</th></tr></thead><tbody><tr><td align="left"><strong>什么是梯度爆炸？</strong></td><td align="left">梯度随层数指数增长，变成天文数字</td></tr><tr><td align="left"><strong>怎么发生的？</strong></td><td align="left">每层权重 &gt; 1，连乘效应导致指数爆炸</td></tr><tr><td align="left"><strong>后果是什么？</strong></td><td align="left">参数飞上天 → Loss 变 NaN → 模型崩溃</td></tr><tr><td align="left"><strong>最直接的解法？</strong></td><td align="left">梯度裁剪（一行代码，立刻生效）</td></tr><tr><td align="left"><strong>治本的解法？</strong></td><td align="left">合理初始化 + 归一化 + 残差连接</td></tr><tr><td align="left"><strong>高发场景？</strong></td><td align="left">RNN、长序列、深层网络、初始化太大</td></tr></tbody></table></div>]]></content>
      
      
      <categories>
          
          <category> AI </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> Transformer </tag>
            
            <tag> AI </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>os之PV</title>
      <link href="/2026/04/28/PV/"/>
      <url>/2026/04/28/PV/</url>
      
        <content type="html"><![CDATA[<p>本文将从定义，如何实现互斥，同步，pv实操三个部分讲解。<br>后补现代cpp的<strong>channal</strong></p>        <h1 id="信号量"   >          <a href="#信号量" class="heading-link"><i class="fas fa-link"></i></a><a href="#信号量" class="headerlink" title="信号量"></a>信号量</h1>      <p>要了解pv,首先要了解信号量。<br>人们为了实现进程同步互斥，为了机器知道运行状态（进程通常分为三个状态，就绪，运行，阻塞），定义了一个变量来表示系统种某种资源的数量。</p><ul><li>如果信号量<strong>S&gt;0</strong>，说明有资源可以使用</li><li>如果信号量<strong>S&lt;0</strong>，说明有进程正在等待这个资源</li><li>如果信号量<strong>S&#x3D;0</strong>，说明资源刚好用完，没有进程在等待<br>那么如何改变信号量，就是<strong>PV操作了</strong></li></ul>        <h1 id="定义理解"   >          <a href="#定义理解" class="heading-link"><i class="fas fa-link"></i></a><a href="#定义理解" class="headerlink" title="定义理解"></a>定义理解</h1>      <div class="table-container"><table><thead><tr><th>原语</th><th>全称（荷兰语）</th><th>含义</th><th>本质动作</th></tr></thead><tbody><tr><td><strong>P</strong></td><td>Proberen</td><td>测试</td><td>申请资源（可能阻塞）</td></tr><tr><td><strong>V</strong></td><td>Verhogen</td><td>增加</td><td>释放资源（唤醒等待者）</td></tr><tr><td>pv原语是操作系统用于实现<strong>进程同步和互斥的原子操作</strong>，由荷兰计算机科学家Dijkstra提出。</td><td></td><td></td><td></td></tr><tr><td>讲一下个人的通俗理解</td><td></td><td></td><td></td></tr></tbody></table></div><ul><li>p是<strong>申请占用一个资源</strong>，<strong>将信号量-1</strong>，如果信号量小于0，就进入阻塞，否则继续进行</li><li>V是<strong>释放一个资源</strong>，<strong>将信号量+1</strong>，我理解为通知，因为释放一个资源后，如果有另一个等待该资源的进程，就可以通知他运行了。简答来说，释放是操作，通知是结果。</li></ul><p><em>可以这么理解，当信号量的值为 2 的时候，表示有 2 个资源可以使用，当信号量的值为 -2 的时候，表示有两个进程正在等待使用这个资源。</em></p>        <h1 id="如何实现互斥"   >          <a href="#如何实现互斥" class="heading-link"><i class="fas fa-link"></i></a><a href="#如何实现互斥" class="headerlink" title="如何实现互斥"></a>如何实现互斥</h1>      <p>总结一下：互斥等于进程共享一个初值为1的信号量，进入临界区前p一下，出来后v一下。</p>        <h2 id="第一步：定义一个互斥信号量mutex"   >          <a href="#第一步：定义一个互斥信号量mutex" class="heading-link"><i class="fas fa-link"></i></a><a href="#第一步：定义一个互斥信号量mutex" class="headerlink" title="第一步：定义一个互斥信号量mutex"></a><strong>第一步：定义一个互斥信号量mutex</strong></h2>      <p>mutex是一个约定俗成的命名，看到就知道是用来做互斥保护临界区的。是 <strong>Mutex</strong>（Mutual Exclusion，互斥锁）的缩写</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">semaphore mutex=<span class="number">1</span><span class="comment">//初始化互斥信号量</span></span><br></pre></td></tr></table></div></figure><p>(semaphore表示信号量类型，有的教材写作 sem_t)<br> <strong>为什么mutex要初始化为1？</strong><br>反过来想，初始化为0会发生什么？<br>第一个进程执行p(mutex)，s-1后s&lt;0直接阻塞自己了</p>        <h2 id="第二步：在临界区前后进行PV"   >          <a href="#第二步：在临界区前后进行PV" class="heading-link"><i class="fas fa-link"></i></a><a href="#第二步：在临界区前后进行PV" class="headerlink" title="第二步：在临界区前后进行PV"></a>第二步：在临界区前后进行PV</h2>      <p>也就是说把对临界资源的访问置于PV操作之间</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">semaphore mutex=<span class="number">-1</span>;</span><br><span class="line"><span class="built_in">p1</span>()&#123;</span><br><span class="line"><span class="built_in">P</span>(mutex);<span class="comment">//申请占用资源</span></span><br><span class="line">临界区</span><br><span class="line"><span class="built_in">V</span>(mutex);<span class="comment">//释放资源</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">p2</span>()&#123;</span><br><span class="line"><span class="built_in">P</span>(mutex);</span><br><span class="line">临界区</span><br><span class="line"><span class="built_in">V</span>(mutex);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>也许你会疑惑p1p2不是重复的吗，但是这是一个重要思想<br><strong>pv操作必须成对出现</strong></p>        <h1 id="如何实现同步"   >          <a href="#如何实现同步" class="heading-link"><i class="fas fa-link"></i></a><a href="#如何实现同步" class="headerlink" title="如何实现同步"></a>如何实现同步</h1>      <p>进程同步就是要各并发进程<strong>有序</strong>进行。比如司机售票员问题。需要售票员先关门，司机才能开车。而不能司机开车了售票员再关门。<br><strong>同步 &#x3D; 在先行进程里V一下（通知），在后行进程里P一下（等待），信号量初值0。</strong></p>        <h2 id="第一步：定义变量"   >          <a href="#第一步：定义变量" class="heading-link"><i class="fas fa-link"></i></a><a href="#第一步：定义变量" class="headerlink" title="第一步：定义变量"></a>第一步：定义变量</h2>      <div class="table-container"><table><thead><tr><th>同步关系</th><th>等待方</th><th>通知方</th><th>信号量命名</th><th>初值</th></tr></thead><tbody><tr><td>关车门 → 启动</td><td>司机</td><td>售票员</td><td><code>start</code></td><td>0</td></tr><tr><td>停车 → 开车门</td><td>售票员</td><td>司机</td><td><code>open</code></td><td>0</td></tr><tr><td><strong>为什么初值是0？</strong></td><td></td><td></td><td></td><td></td></tr><tr><td>如果初值是1的话，不管售票员管没关门，司机都可以开车，同步就失效了。</td><td></td><td></td><td></td><td></td></tr><tr><td>设置为0，那么先跑的人一定会被阻塞，从而实现“后行进程必须等待先行进程”</td><td></td><td></td><td></td><td></td></tr></tbody></table></div><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">semaphore event=<span class="number">0</span>;</span><br></pre></td></tr></table></div></figure>        <h2 id="第二步：对每个对象进行思考"   >          <a href="#第二步：对每个对象进行思考" class="heading-link"><i class="fas fa-link"></i></a><a href="#第二步：对每个对象进行思考" class="headerlink" title="第二步：对每个对象进行思考"></a>第二步：对每个对象进行思考</h2>      <p>比如司机，需要进行开车停车，售票员则需要进行开门关门。关系为：<br>停车后-&gt;开门<br>关门后-&gt;开车<br>所以对于司机，他需要等待关门P,然后开车，车停后通知售票员开门V。<br>对于售票员，他需要通知司机可以启动V,然后等司机关门后停车P。</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">司机() &#123;</span><br><span class="line">    <span class="keyword">while</span>(<span class="number">1</span>) &#123;</span><br><span class="line">        <span class="built_in">P</span>(start);        <span class="comment">//  等关门</span></span><br><span class="line">        启动车辆();</span><br><span class="line">        正常行驶();</span><br><span class="line">        到站停车();</span><br><span class="line">        <span class="built_in">V</span>(open);         <span class="comment">//  通知售票员：可以开门了</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">售票员() &#123;</span><br><span class="line">    <span class="keyword">while</span>(<span class="number">1</span>) &#123;</span><br><span class="line">        关车门();</span><br><span class="line">        <span class="built_in">V</span>(start);        <span class="comment">// 通知司机：可以启动了</span></span><br><span class="line">        售票();</span><br><span class="line">        <span class="built_in">P</span>(open);         <span class="comment">//  等停车</span></span><br><span class="line">        开车门();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p><strong>为什么 <code>V(start)</code> 要放在 <code>售票()</code> 之前，而不是之后？</strong><br>因为<strong>V 应该尽早发</strong>（条件满足就立刻发通知），不需要等把本进程所有事做完。<br>这样可以提高并发度。</p>        <h1 id="PV实例题目"   >          <a href="#PV实例题目" class="heading-link"><i class="fas fa-link"></i></a><a href="#PV实例题目" class="headerlink" title="PV实例题目"></a>PV实例题目</h1>              <h2 id="1-家人吃水果（同步）"   >          <a href="#1-家人吃水果（同步）" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-家人吃水果（同步）" class="headerlink" title="1.家人吃水果（同步）"></a>1.家人吃水果（同步）</h2>              <h3 id="题目"   >          <a href="#题目" class="heading-link"><i class="fas fa-link"></i></a><a href="#题目" class="headerlink" title="题目"></a>题目</h3>      <p>v桌上有一空盘，最多允许存放一只水果。爸爸可向盘中放一个苹果或放一个桔子，儿子专等吃盘中的桔子，女儿专等吃苹果。<br>试用P、V操作实现爸爸、儿子、女儿三个并发进程的同步。</p>        <h3 id="思路"   >          <a href="#思路" class="heading-link"><i class="fas fa-link"></i></a><a href="#思路" class="headerlink" title="思路"></a>思路</h3>      <ul><li>设置信号量表示不同操作对象的状态</li><li>思考每个主体需要做的事</li></ul><p>这道题目来说，盘子有一个，盘子有三个状态（空盘，桔子，苹果）。那我设置三个信号量S,So，Sa，表示是否空盘。能否取桔子和苹果。<br>然后对于爸爸来说，他需要等盘子空（p(s)），然后放水果。如果是苹果就要通知女儿(V（Sa）)。反之亦然。<br>对于女儿来说，她需要等待苹果（p(Sa)），如果等到了她拿走，就要通知爸爸盘子空了(V(S))</p>        <h2 id="代码"   >          <a href="#代码" class="heading-link"><i class="fas fa-link"></i></a><a href="#代码" class="headerlink" title="代码"></a>代码</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line">semaphore S = <span class="number">1</span>;    <span class="comment">// 空盘信号量（初值1：一开始是空盘）</span></span><br><span class="line">semaphore So = <span class="number">0</span>;   <span class="comment">// 桔子信号量（初值0：一开始没有桔子）</span></span><br><span class="line">semaphore Sa = <span class="number">0</span>;   <span class="comment">// 苹果信号量（初值0：一开始没有苹果）</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 爸爸进程</span></span><br><span class="line"><span class="built_in">father</span>() &#123;</span><br><span class="line">    <span class="keyword">while</span>(<span class="number">1</span>) &#123;</span><br><span class="line">        <span class="built_in">P</span>(S);           <span class="comment">// 等盘子空（盘子必须是空才能放）</span></span><br><span class="line">        放水果();</span><br><span class="line">        <span class="keyword">if</span> (放的是桔子) &#123;</span><br><span class="line">            <span class="built_in">V</span>(So);      <span class="comment">// 通知儿子：有桔子了</span></span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="built_in">V</span>(Sa);      <span class="comment">// 通知女儿：有苹果了</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 儿子进程</span></span><br><span class="line"><span class="built_in">son</span>() &#123;</span><br><span class="line">    <span class="keyword">while</span>(<span class="number">1</span>) &#123;</span><br><span class="line">        <span class="built_in">P</span>(So);          <span class="comment">// 等盘子里有桔子</span></span><br><span class="line">        取桔子();</span><br><span class="line">        <span class="built_in">V</span>(S);           <span class="comment">// 通知爸爸：盘子空了（因为桔子被取走了）</span></span><br><span class="line">        吃桔子();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 女儿进程</span></span><br><span class="line"><span class="built_in">daughter</span>() &#123;</span><br><span class="line">    <span class="keyword">while</span>(<span class="number">1</span>) &#123;</span><br><span class="line">        <span class="built_in">P</span>(Sa);          <span class="comment">// 等盘子里有苹果</span></span><br><span class="line">        </span><br><span class="line">        取苹果();</span><br><span class="line">        <span class="built_in">V</span>(S);           <span class="comment">// 通知爸爸：盘子空了（因为苹果被取走了）</span></span><br><span class="line">        </span><br><span class="line">        吃苹果();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="2-读者登记表（互斥）"   >          <a href="#2-读者登记表（互斥）" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-读者登记表（互斥）" class="headerlink" title="2.读者登记表（互斥）"></a>2.读者登记表（互斥）</h2>              <h3 id="题目-1"   >          <a href="#题目-1" class="heading-link"><i class="fas fa-link"></i></a><a href="#题目-1" class="headerlink" title="题目"></a>题目</h3>      <p>有一阅览室，读者进入时必须先在一张登记表上进行登记，该表为每一座位列一表目，包括座号和读者姓名。读者离开时要消掉登记信号，阅览室中共有100个座位，请写出算法。<br>注意：不是生产者-消费者关系，而是多个读者共享一个登记表，<strong>所以主要是互斥</strong></p>        <h3 id="思路-1"   >          <a href="#思路-1" class="heading-link"><i class="fas fa-link"></i></a><a href="#思路-1" class="headerlink" title="思路"></a><strong>思路</strong></h3>      <ul><li>找出资源和约束定义变量</li><li>理出流程</li></ul><p>资源是座位和登记表，约束是，没有空座不能进，登记表只能一个人用。所以seats用来计数（初始值100），mutex用来保护登记表（初始时置为1）。</p><p>流程为：读者进入，申请座位。如果有座位就登记，登记完释放。阅读走之后再登记，再释放，然后释放座位。</p><p><strong>为什么不能先释放座位再登记？</strong>，其实可以，但这样更优雅。<br>如果先 <code>V(seats)</code> 再注销：</p><ul><li>座位已经释放了，其他读者可能被唤醒并进来</li><li>但这个人<strong>还占着登记表</strong>在注销</li><li>新进来的读者在 <code>P(mutex)</code> 那里等</li><li>逻辑上没问题，但<strong>登记表被占用的时间变长了</strong><br>标准做法让登记表尽快释放。</li></ul>        <h3 id="代码-1"   >          <a href="#代码-1" class="heading-link"><i class="fas fa-link"></i></a><a href="#代码-1" class="headerlink" title="代码"></a>代码</h3>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">semaphore seats = <span class="number">100</span>;   <span class="comment">// 空座位数</span></span><br><span class="line">semaphore mutex = <span class="number">1</span>;     <span class="comment">// 登记表互斥信号量</span></span><br><span class="line"><span class="comment">// 读者进程</span></span><br><span class="line"><span class="built_in">reader</span>() &#123;</span><br><span class="line">    <span class="keyword">while</span>(<span class="number">1</span>) &#123;</span><br><span class="line">        <span class="built_in">P</span>(seats);        <span class="comment">// 1. 申请座位（没空就等）</span></span><br><span class="line">        <span class="built_in">P</span>(mutex);        <span class="comment">// 2. 申请登记表</span></span><br><span class="line">        登记();           <span class="comment">// 写信息</span></span><br><span class="line">        <span class="built_in">V</span>(mutex);        <span class="comment">// 3. 释放登记表</span></span><br><span class="line">        阅读();           <span class="comment">// 4. 读书</span></span><br><span class="line">        <span class="built_in">P</span>(mutex);        <span class="comment">// 5. 申请登记表</span></span><br><span class="line">        注销();           <span class="comment">// 删信息</span></span><br><span class="line">        <span class="built_in">V</span>(mutex);        <span class="comment">// 6. 释放登记表</span></span><br><span class="line">        <span class="built_in">V</span>(seats);        <span class="comment">// 7. 释放座位</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="channal"   >          <a href="#channal" class="heading-link"><i class="fas fa-link"></i></a><a href="#channal" class="headerlink" title="channal"></a>channal</h1>              <h2 id="对比"   >          <a href="#对比" class="heading-link"><i class="fas fa-link"></i></a><a href="#对比" class="headerlink" title="对比"></a>对比</h2>      <ul><li>用<strong>PV操作</strong>，是自己在管理“等待”和“通知”的逻辑。</li><li>用<strong>Channel</strong>，是把数据交给通道，同步的逻辑由通道自动完成。<br>可以将Channel理解为<strong>在更高编程语言层面，对PV操作和信号量机制的一种封装和升级</strong>。</li></ul>        <h3 id="channel-的两种主要同步模式"   >          <a href="#channel-的两种主要同步模式" class="heading-link"><i class="fas fa-link"></i></a><a href="#channel-的两种主要同步模式" class="headerlink" title="channel 的两种主要同步模式"></a>channel 的两种主要同步模式</h3>              <h4 id="1-同步（无缓冲）Channel：强制握手"   >          <a href="#1-同步（无缓冲）Channel：强制握手" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-同步（无缓冲）Channel：强制握手" class="headerlink" title="1. 同步（无缓冲）Channel：强制握手"></a>1. 同步（无缓冲）Channel：强制握手</h4>      <p>这是最纯粹的“通道即同步”模式。在C++的CSP（Communicating Sequential Processes）库或类似实现中最为典型</p><ul><li><strong>核心机制</strong>：一个发送操作必须等到一个接收操作准备好，两者才会“相遇”（Rendezvous），完成数据传输。在此之前，双方都会<strong>阻塞</strong>等待</li><li><strong>同步效果</strong>：它强制生产者和消费者在某一时刻同步，无需任何额外的锁或条件变量，就能保证“数据被发送”这一事件与“数据被接收”这一事件同时发生。</li><li><strong>代码示例（概念性）</strong>：</li></ul><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">// 伪代码，展示同步通道的行为</span><br><span class="line">channel&lt;int&gt; sync_chan; // 假设这是一个同步（无缓冲）通道</span><br><span class="line"></span><br><span class="line">// 线程 A (发送者)</span><br><span class="line">sync_chan.send(42);     // 此处会阻塞，直到线程B准备好接收</span><br><span class="line"></span><br><span class="line">// 线程 B (接收者)</span><br><span class="line">int value = sync_chan.receive(); // 此处会阻塞，直到线程A发送数据</span><br><span class="line">// 当线程A的send和线程B的receive都执行到对应行时，数据被原子地传递，</span><br><span class="line">// 然后两个线程可以继续执行。</span><br></pre></td></tr></table></div></figure>        <h4 id="2-异步（缓冲）Channel：解耦通信与同步"   >          <a href="#2-异步（缓冲）Channel：解耦通信与同步" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-异步（缓冲）Channel：解耦通信与同步" class="headerlink" title="2. 异步（缓冲）Channel：解耦通信与同步"></a>2. 异步（缓冲）Channel：解耦通信与同步</h4>      <p>这种模式更侧重于<strong>通信</strong>，同步是作为队列满或空时的边界条件存在。</p><ul><li><strong>核心机制</strong>：通道内部有一个缓冲区。发送者将数据放入缓冲区，如果缓冲区没满，就立即返回，不会阻塞。接收者从缓冲区取数据，如果缓冲区不为空，也立即返回</li><li><strong>同步效果</strong>：<ul><li><strong>生产快于消费</strong>：当缓冲区<strong>满了</strong>，下一次<code>send</code>操作就会阻塞，直到消费者取走数据。此时，生产者被<strong>同步</strong>到消费者的进度上。</li><li><strong>消费快于生产</strong>：当缓冲区<strong>空了</strong>，下一次<code>receive</code>操作就会阻塞，直到生产者放入新数据。此时，消费者被<strong>同步</strong>到生产者的进度上。</li></ul></li><li><strong>代码示例（Boost.Fiber）</strong>：</li></ul><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;boost/fiber/buffered_channel.hpp&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;boost/fiber/fiber.hpp&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 创建一个容量为2的缓冲通道</span></span><br><span class="line">    boost::fibers::buffered_channel&lt;<span class="type">int</span>&gt; chan&#123;<span class="number">2</span>&#125;;</span><br><span class="line"></span><br><span class="line">    boost::<span class="function">fibers::fiber <span class="title">producer</span><span class="params">([&amp;chan] &#123;</span></span></span><br><span class="line"><span class="params"><span class="function">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; <span class="number">5</span>; ++i) &#123;</span></span></span><br><span class="line"><span class="params"><span class="function">            chan.push(i); <span class="comment">// push 操作可能因为队列满而阻塞</span></span></span></span><br><span class="line"><span class="params"><span class="function">            std::cout &lt;&lt; <span class="string">&quot;Produced: &quot;</span> &lt;&lt; i &lt;&lt; std::endl;</span></span></span><br><span class="line"><span class="params"><span class="function">        &#125;</span></span></span><br><span class="line"><span class="params"><span class="function">        chan.close();</span></span></span><br><span class="line"><span class="params"><span class="function">    &#125;)</span></span>;</span><br><span class="line"></span><br><span class="line">    boost::<span class="function">fibers::fiber <span class="title">consumer</span><span class="params">([&amp;chan] &#123;</span></span></span><br><span class="line"><span class="params"><span class="function">        <span class="type">int</span> i;</span></span></span><br><span class="line"><span class="params"><span class="function">        <span class="keyword">while</span> (boost::fibers::channel_op_status::success == chan.pop(i)) &#123;</span></span></span><br><span class="line"><span class="params"><span class="function">            std::cout &lt;&lt; <span class="string">&quot;Consumed: &quot;</span> &lt;&lt; i &lt;&lt; std::endl;</span></span></span><br><span class="line"><span class="params"><span class="function">            <span class="comment">// pop 操作可能因为队列空而阻塞</span></span></span></span><br><span class="line"><span class="params"><span class="function">        &#125;</span></span></span><br><span class="line"><span class="params"><span class="function">    &#125;)</span></span>;</span><br><span class="line"></span><br><span class="line">    producer.<span class="built_in">join</span>();</span><br><span class="line">    consumer.<span class="built_in">join</span>();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>]]></content>
      
      
      <categories>
          
          <category> csdiy实验 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> cs162 </tag>
            
            <tag> 操作系统 </tag>
            
            <tag> csdiy </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>CS162笔记第二章（操作系统）</title>
      <link href="/2026/03/23/CS162%E7%AC%AC%E4%BA%8C%E7%AB%A0/"/>
      <url>/2026/03/23/CS162%E7%AC%AC%E4%BA%8C%E7%AB%A0/</url>
      
        <content type="html"><![CDATA[        <h2 id="一、课程开篇：回顾上一讲核心"   >          <a href="#一、课程开篇：回顾上一讲核心" class="heading-link"><i class="fas fa-link"></i></a><a href="#一、课程开篇：回顾上一讲核心" class="headerlink" title="一、课程开篇：回顾上一讲核心"></a>一、课程开篇：回顾上一讲核心</h2>      <p>上一讲我们讲了操作系统的<strong>三大角色</strong>：</p><ol><li><p>裁判（Referee）</p><p>管理资源、保护、隔离、权限，不让进程互相干扰。</p></li><li><p>幻术师（Illusionist）</p><p>把丑陋硬件变成干净、易用的虚拟资源（线程、地址空间、文件等）。</p></li><li><p>粘合剂（Glue）</p><p>提供统一服务（窗口、文件系统、网络），让写程序更简单。</p></li></ol><p>老师强调：</p><p>同一个物理硬件上，可以<strong>同时运行多个进程</strong>，每个进程都以为自己独占整台机器。</p><p>进程之间<strong>禁止互相访问 &#x2F; 修改</strong>对方状态，也不能非法修改操作系统或存储。</p><p>一旦违规 → 操作系统直接终止进程 → <strong>段错误（segmentation fault）</strong>。</p><hr>        <h2 id="二、硬件为什么极度复杂？"   >          <a href="#二、硬件为什么极度复杂？" class="heading-link"><i class="fas fa-link"></i></a><a href="#二、硬件为什么极度复杂？" class="headerlink" title="二、硬件为什么极度复杂？"></a>二、硬件为什么极度复杂？</h2>      <p>老师用 <strong>Skylake 处理器架构</strong> 举例：</p><ul><li>CPU 直连高带宽 DRAM、高速显卡</li><li>通过 DMI 接口连接 <strong>PCH 芯片组（原南桥）</strong></li><li>下面挂着：PCIe 高速设备、磁盘、USB、网口、音频、raid 等</li><li>再下层还有更低速的设备</li></ul><p><strong>结论：</strong></p><p>硬件极其杂乱、多样、复杂 → <strong>必须由操作系统来管理与抽象</strong>。</p><hr>        <h2 id="三、系统复杂度的直观体现：代码行数"   >          <a href="#三、系统复杂度的直观体现：代码行数" class="heading-link"><i class="fas fa-link"></i></a><a href="#三、系统复杂度的直观体现：代码行数" class="headerlink" title="三、系统复杂度的直观体现：代码行数"></a>三、系统复杂度的直观体现：代码行数</h2>      <ul><li><p>Linux 从 2.2 到 3.1，代码量增长 <strong>6 倍以上</strong></p></li><li><p>现代汽车：<strong>约 1 亿行代码</strong></p></li><li><p>设备驱动（第三方开发）是 </p><p>BUG 重灾区</p><p>统计：超过 </p><p>50%~60% 的系统崩溃来自驱动程序</p></li><li><p>安全漏洞：Spectre、Meltdown（投机执行导致内核数据泄露）</p></li></ul><p><strong>老师核心观点：</strong></p><p>操作系统的根本意义：<strong>抽象硬件、驯服复杂度</strong>。</p><hr>        <h2 id="四、操作系统如何-“化繁为简”？（核心抽象）"   >          <a href="#四、操作系统如何-“化繁为简”？（核心抽象）" class="heading-link"><i class="fas fa-link"></i></a><a href="#四、操作系统如何-“化繁为简”？（核心抽象）" class="headerlink" title="四、操作系统如何 “化繁为简”？（核心抽象）"></a>四、操作系统如何 “化繁为简”？（核心抽象）</h2>      <p>硬件太烂 → OS 换成更好用的虚拟概念：</p><ul><li>物理 CPU → <strong>线程（Thread）</strong></li><li>物理内存（零散 DRAM）→ <strong>地址空间（Address Space）</strong></li><li>磁盘 &#x2F; SSD 裸数据块 → <strong>文件系统（File System）</strong></li><li>原始网络包 → <strong>Socket 接口</strong></li><li>裸机 → <strong>进程（Process）</strong></li></ul><hr>        <h1 id="五、本节课正式内容：操作系统-四大基本概念（必考）"   >          <a href="#五、本节课正式内容：操作系统-四大基本概念（必考）" class="heading-link"><i class="fas fa-link"></i></a><a href="#五、本节课正式内容：操作系统-四大基本概念（必考）" class="headerlink" title="五、本节课正式内容：操作系统 四大基本概念（必考）"></a>五、本节课正式内容：操作系统 <strong>四大基本概念</strong>（必考）</h1>      <p>老师明确：今天讲 <strong>4 个 OS 最基础概念</strong>，全程围绕它们展开。</p><hr>        <h2 id="概念一：线程（Thread）—-执行流"   >          <a href="#概念一：线程（Thread）—-执行流" class="heading-link"><i class="fas fa-link"></i></a><a href="#概念一：线程（Thread）—-执行流" class="headerlink" title="概念一：线程（Thread）— 执行流"></a>概念一：线程（Thread）— 执行流</h2>              <h3 id="1-线程是什么？"   >          <a href="#1-线程是什么？" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-线程是什么？" class="headerlink" title="1. 线程是什么？"></a>1. 线程是什么？</h3>      <p><strong>线程 &#x3D; 一个独立的执行上下文（execution context）</strong></p><p>包含：</p><ul><li>程序计数器（PC）</li><li>寄存器集合</li><li>执行标志（flags）</li><li>栈（stack）</li><li>相关内存状态</li></ul>        <h3 id="2-线程-虚拟化的-CPU（核心）"   >          <a href="#2-线程-虚拟化的-CPU（核心）" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-线程-虚拟化的-CPU（核心）" class="headerlink" title="2. 线程 &#x3D; 虚拟化的 CPU（核心）"></a>2. 线程 &#x3D; 虚拟化的 CPU（核心）</h3>      <p>你在 61C 学的是物理 CPU 的取指执行。</p><p>OS 把它虚拟化 → 变成<strong>线程</strong>。</p>        <h3 id="3-常驻（resident）是什么意思？"   >          <a href="#3-常驻（resident）是什么意思？" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-常驻（resident）是什么意思？" class="headerlink" title="3. 常驻（resident）是什么意思？"></a>3. 常驻（resident）是什么意思？</h3>      <p>当线程的 <strong>上下文在 CPU 寄存器里</strong>，它就是正在运行、常驻的。</p><p>一个核（core）<strong>同一时刻只能有一个线程常驻</strong>。</p>        <h3 id="4-线程挂起（suspended）"   >          <a href="#4-线程挂起（suspended）" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-线程挂起（suspended）" class="headerlink" title="4. 线程挂起（suspended）"></a>4. 线程挂起（suspended）</h3>      <ul><li>上下文不在寄存器里</li><li>被保存到内存中的 <strong>TCB（Thread Control Block，线程控制块）</strong></li><li>程序计数器不再指向它</li></ul>        <h3 id="5-多线程-“并发”-幻觉怎么实现？"   >          <a href="#5-多线程-“并发”-幻觉怎么实现？" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-多线程-“并发”-幻觉怎么实现？" class="headerlink" title="5. 多线程 “并发” 幻觉怎么实现？"></a>5. 多线程 “并发” 幻觉怎么实现？</h3>      <p><strong>单 CPU &#x3D; 时分多路复用（time multiplexing）</strong></p><ul><li>运行线程 A 一小会儿</li><li>切换</li><li>运行线程 B 一小会儿</li><li>切换</li><li>运行线程 C…</li></ul><p>因为切换极快 → 人感觉 “同时运行”。</p>        <h3 id="6-上下文切换（context-switch）做什么？"   >          <a href="#6-上下文切换（context-switch）做什么？" class="heading-link"><i class="fas fa-link"></i></a><a href="#6-上下文切换（context-switch）做什么？" class="headerlink" title="6. 上下文切换（context switch）做什么？"></a>6. 上下文切换（context switch）做什么？</h3>      <ol><li>把当前线程所有寄存器、PC、栈指针保存到内存 <strong>TCB</strong></li><li>加载下一个线程的上下文到 CPU</li><li>开始执行新线程</li></ol><p>切换耗时：<strong>几微秒</strong></p><p>不能切换太快，否则大部分时间都在切换（颠簸 &#x2F;thrashing）。</p><hr>        <h2 id="概念二：地址空间（Address-Space）"   >          <a href="#概念二：地址空间（Address-Space）" class="heading-link"><i class="fas fa-link"></i></a><a href="#概念二：地址空间（Address-Space）" class="headerlink" title="概念二：地址空间（Address Space）"></a>概念二：地址空间（Address Space）</h2>              <h3 id="1-定义"   >          <a href="#1-定义" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-定义" class="headerlink" title="1. 定义"></a>1. 定义</h3>      <p><strong>地址空间 &#x3D; 程序可访问的所有地址集合 + 对应状态</strong></p><p>例：32 位地址空间</p><p><code>0 ~ 0xFFFFFFFF</code>（约 4GB）</p>        <h3 id="2-地址空间内部布局"   >          <a href="#2-地址空间内部布局" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-地址空间内部布局" class="headerlink" title="2. 地址空间内部布局"></a>2. 地址空间内部布局</h3>      <ul><li><strong>代码段（text&#x2F;code）</strong>：指令</li><li><strong>静态数据段（data）</strong>：全局变量、静态变量、字符串常量</li><li><strong>栈（stack）</strong>：局部变量、函数调用</li><li><strong>堆（heap）</strong>：malloc 分配的内存</li></ul>        <h3 id="3-早期简单保护：基址-界限（Base-Bound）"   >          <a href="#3-早期简单保护：基址-界限（Base-Bound）" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-早期简单保护：基址-界限（Base-Bound）" class="headerlink" title="3. 早期简单保护：基址 + 界限（Base + Bound）"></a>3. 早期简单保护：基址 + 界限（Base + Bound）</h3>      <p>最早的硬件保护方案：</p><ul><li>两个寄存器：<strong>基址、界限</strong></li><li>程序只能访问 <code>[base, bound]</code> 之间的内存</li><li>访问越界 → 直接报错</li></ul><p>优点：简单、硬件成本低</p><p>缺点：扩展麻烦、会产生内存碎片</p>        <h3 id="4-进阶：地址翻译（虚拟内存）"   >          <a href="#4-进阶：地址翻译（虚拟内存）" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-进阶：地址翻译（虚拟内存）" class="headerlink" title="4. 进阶：地址翻译（虚拟内存）"></a>4. 进阶：地址翻译（虚拟内存）</h3>      <p>后面课程重点：</p><p>把程序使用的 <strong>虚拟地址 → 页表翻译 → 物理地址</strong></p><ul><li>无碎片</li><li>可以离散存放</li><li>可以置换到磁盘</li><li>可以隔离保护</li></ul><hr>        <h2 id="概念三：进程（Process）—-本讲最重要"   >          <a href="#概念三：进程（Process）—-本讲最重要" class="heading-link"><i class="fas fa-link"></i></a><a href="#概念三：进程（Process）—-本讲最重要" class="headerlink" title="概念三：进程（Process）— 本讲最重要"></a>概念三：进程（Process）— 本讲最重要</h2>              <h3 id="1-进程是什么？"   >          <a href="#1-进程是什么？" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-进程是什么？" class="headerlink" title="1. 进程是什么？"></a>1. 进程是什么？</h3>      <p><strong>进程 &#x3D; 带权限限制的执行环境</strong></p><p>&#x3D; <strong>保护后的地址空间 + 一个或多个线程 + 文件等资源</strong></p>        <h3 id="2-为什么需要进程？"   >          <a href="#2-为什么需要进程？" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-为什么需要进程？" class="headerlink" title="2. 为什么需要进程？"></a>2. 为什么需要进程？</h3>      <p>早期只有线程：</p><ul><li>所有线程共享<strong>同一份地址空间</strong></li><li>一个线程崩溃 → 全盘崩溃</li><li>线程可互相改写内存、窃取数据</li><li>线程可以改写操作系统 → 系统直接挂掉</li></ul><p><strong>进程 &#x3D; 隔离 + 保护 + 权限</strong></p>        <h3 id="3-进程核心特性"   >          <a href="#3-进程核心特性" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-进程核心特性" class="headerlink" title="3. 进程核心特性"></a>3. 进程核心特性</h3>      <ul><li>每个进程有<strong>独立地址空间</strong></li><li>进程之间<strong>无法互相访问</strong></li><li>一个进程崩了 → 不影响其他</li><li>OS 受保护，不会被随意破坏</li></ul>        <h3 id="4-进程-vs-线程（老师反复强调）"   >          <a href="#4-进程-vs-线程（老师反复强调）" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-进程-vs-线程（老师反复强调）" class="headerlink" title="4. 进程 vs 线程（老师反复强调）"></a>4. 进程 vs 线程（老师反复强调）</h3>      <ul><li><strong>进程：资源容器、保护单位</strong>（地址空间、文件、权限）</li><li><strong>线程：执行单位、活跃单位</strong>（PC、寄存器、栈）</li><li>一个进程至少有一个线程</li><li>同一进程内的线程共享地址空间</li><li>不同进程完全隔离</li></ul><hr>        <h2 id="概念四：双重模式（Dual-Mode）—-安全基石"   >          <a href="#概念四：双重模式（Dual-Mode）—-安全基石" class="heading-link"><i class="fas fa-link"></i></a><a href="#概念四：双重模式（Dual-Mode）—-安全基石" class="headerlink" title="概念四：双重模式（Dual Mode）— 安全基石"></a>概念四：双重模式（Dual Mode）— 安全基石</h2>              <h3 id="1-处理器至少两种模式："   >          <a href="#1-处理器至少两种模式：" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-处理器至少两种模式：" class="headerlink" title="1. 处理器至少两种模式："></a>1. 处理器至少两种模式：</h3>      <ol><li><p>内核模式（Kernel Mode &#x2F; Supervisor）</p><ul><li>全权访问所有资源</li><li>可以修改页表、关中断、操作硬件</li></ul></li><li><p>用户模式（User Mode）</p><ul><li>权限受限</li><li><strong>不能</strong>修改页表</li><li><strong>不能</strong>关中断</li><li><strong>不能</strong>直接访问硬件</li></ul></li></ol>        <h3 id="2-为什么需要双模式？"   >          <a href="#2-为什么需要双模式？" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-为什么需要双模式？" class="headerlink" title="2. 为什么需要双模式？"></a>2. 为什么需要双模式？</h3>      <p>防止用户程序：</p><ul><li>霸占 CPU（死循环不放手）</li><li>破坏操作系统</li><li>访问别的进程数据</li><li>随意操控硬件</li></ul>        <h3 id="3-如何进入内核模式？（仅三种合法入口）"   >          <a href="#3-如何进入内核模式？（仅三种合法入口）" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-如何进入内核模式？（仅三种合法入口）" class="headerlink" title="3. 如何进入内核模式？（仅三种合法入口）"></a>3. 如何进入内核模式？（仅三种合法入口）</h3>      <ol><li><strong>系统调用（system call）</strong>：进程主动请求服务</li><li><strong>中断（interrupt）</strong>：时钟、磁盘、网络等事件</li><li><strong>异常 &#x2F; 陷阱（exception&#x2F;trap）</strong>：除零、缺页、非法访问</li></ol><p>→ 所有入口都<strong>由操作系统严格控制</strong>。</p><hr>        <h1 id="六、完整运行模型（老师最终总结图）"   >          <a href="#六、完整运行模型（老师最终总结图）" class="heading-link"><i class="fas fa-link"></i></a><a href="#六、完整运行模型（老师最终总结图）" class="headerlink" title="六、完整运行模型（老师最终总结图）"></a>六、完整运行模型（老师最终总结图）</h1>      <ol><li><p>程序从磁盘加载</p></li><li><p>操作系统创建</p><p>进程</p><ul><li>分配独立地址空间</li><li>建立页表</li><li>分配栈、堆</li></ul></li><li><p>从入口开始执行，运行在<strong>用户模式</strong></p></li><li><p>需要服务 → 系统调用 → 进入<strong>内核模式</strong></p></li><li><p>内核完成操作，返回用户态</p></li><li><p>时钟中断触发 → 操作系统切换进程</p></li></ol><hr>        <h1 id="七、本节课所有管理与作业提醒（全覆盖）"   >          <a href="#七、本节课所有管理与作业提醒（全覆盖）" class="heading-link"><i class="fas fa-link"></i></a><a href="#七、本节课所有管理与作业提醒（全覆盖）" class="headerlink" title="七、本节课所有管理与作业提醒（全覆盖）"></a>七、本节课所有管理与作业提醒（全覆盖）</h1>      <ul><li><strong>作业 0（Homework 0）</strong>：立刻开始，熟悉工具、GDB、编译、虚拟机</li><li><strong>Project 0</strong>：明天发布，独立完成，不许合作</li><li>项目缓交天数（slip days）：作业与项目共用 <strong>4 天</strong></li><li>本周五是 <strong>退课截止日期（drop date）</strong></li><li>可选 C&#x2F;C++ 复习课：明天举行</li><li>课程全程使用 <strong>C 语言</strong>，项目在 Pintos 操作系统上开发</li></ul><hr>        <h1 id="八、老师强调的易错点（必看）"   >          <a href="#八、老师强调的易错点（必看）" class="heading-link"><i class="fas fa-link"></i></a><a href="#八、老师强调的易错点（必看）" class="headerlink" title="八、老师强调的易错点（必看）"></a>八、老师强调的易错点（必看）</h1>      <ol><li><strong>线程不自带缓存</strong>，一个核的缓存被所有线程共享</li><li>线程不在 CPU 运行时，状态存在 <strong>TCB（内存里）</strong></li><li>进程 &#x3D; 保护单位；线程 &#x3D; 执行单位</li><li>没有地址翻译 + 双模式 → 系统完全不安全</li><li>早期系统（Win3.1、Mac 早期）无强保护 → 极易崩溃</li><li>上下文切换需要保存与恢复 <strong>全部寄存器</strong></li></ol><hr>        <h1 id="九、本讲最终结论（老师原话总结）"   >          <a href="#九、本讲最终结论（老师原话总结）" class="heading-link"><i class="fas fa-link"></i></a><a href="#九、本讲最终结论（老师原话总结）" class="headerlink" title="九、本讲最终结论（老师原话总结）"></a>九、本讲最终结论（老师原话总结）</h1>      <p>现代操作系统建立在 <strong>四大基本概念</strong> 之上：</p><ol><li><strong>线程（Thread）</strong>：执行流、虚拟化 CPU</li><li><strong>地址空间（Address Space）</strong>：内存视图</li><li><strong>进程（Process）</strong>：受保护的执行环境</li><li><strong>双重模式（Dual Mode）</strong>：内核态 &#x2F; 用户态，安全基础</li></ol><p>它们一起实现：<strong>虚拟化、隔离、保护、并发</strong>。</p>]]></content>
      
      
      <categories>
          
          <category> csdiy实验 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> cs162 </tag>
            
            <tag> 操作系统 </tag>
            
            <tag> csdiy </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>计网笔记（中科大郑郑烇、杨坚）</title>
      <link href="/2026/03/20/%E8%AE%A1%E7%BD%91/"/>
      <url>/2026/03/20/%E8%AE%A1%E7%BD%91/</url>
      
        <content type="html"><![CDATA[<p><span class="exturl"><a class="exturl__link"   href="https://www.bilibili.com/video/BV1JV411t7ow?vd_source=6f3b9bab813c14ca00fbb56363a43d7e&p=3&spm_id_from=333.788.videopod.episodes" >1.1 什么是Internet？_哔哩哔哩_bilibili</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p><p>本文通过b站视频字幕整理</p>        <h2 id="一、本章整体内容框架"   >          <a href="#一、本章整体内容框架" class="heading-link"><i class="fas fa-link"></i></a><a href="#一、本章整体内容框架" class="headerlink" title="一、本章整体内容框架"></a>一、本章整体内容框架</h2>      <ol><li>基础概念：网络 → 计算机网络 → Internet</li><li>核心要素：<strong>协议（Protocol）</strong></li><li>网络三大组成：<strong>网络边缘、接入网、核心网</strong></li><li>核心交换：<strong>线路交换、分组交换</strong></li><li>网络结构：<strong>网络的网络（ISP 层次）</strong></li><li>性能指标：丢包、延迟、吞吐量</li><li>核心思想：<strong>分层体系结构</strong></li><li>拓展：Internet 发展历史</li></ol><hr>        <h2 id="二、基础概念：从网络到互联网"   >          <a href="#二、基础概念：从网络到互联网" class="heading-link"><i class="fas fa-link"></i></a><a href="#二、基础概念：从网络到互联网" class="headerlink" title="二、基础概念：从网络到互联网"></a>二、基础概念：从网络到互联网</h2>              <h3 id="1-网络（通用定义）"   >          <a href="#1-网络（通用定义）" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-网络（通用定义）" class="headerlink" title="1. 网络（通用定义）"></a>1. 网络（通用定义）</h3>      <ul><li>本质：<strong>节点 + 边</strong> 构成的拓扑关系</li><li>与大小、形状无关，只看连接关系</li><li>例子：电话网、社交网、蜘蛛网、神经网络</li></ul>        <h3 id="2-计算机网络"   >          <a href="#2-计算机网络" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-计算机网络" class="headerlink" title="2. 计算机网络"></a>2. 计算机网络</h3>      <ul><li><p>定义：<strong>联网的计算机构成的系统</strong></p></li><li><p>两类节点</p><ul><li><p><strong>主机节点（端系统 &#x2F; Host）</strong></p><p>：数据的源与目标</p><ul><li>PC、手机、平板、服务器、IoT 设备</li></ul></li><li><p><strong>数据交换节点</strong></p><p>：只转发，不产生 &#x2F; 不消费数据</p><ul><li>交换机（链路层）、路由器（网络层）、负载均衡设备</li></ul></li></ul></li><li><p>两类链路</p><ul><li><strong>接入链路</strong>：主机 ↔ 交换节点</li><li><strong>骨干链路</strong>：交换节点 ↔ 交换节点</li></ul></li></ul>        <h3 id="3-Internet（互联网）"   >          <a href="#3-Internet（互联网）" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-Internet（互联网）" class="headerlink" title="3. Internet（互联网）"></a>3. Internet（互联网）</h3>      <ul><li>定义：以 <strong>TCP&#x2F;IP 协议族</strong> 为核心，由大量网络通过路由器互联而成的 <strong>网络的网络</strong></li><li>区分<ul><li>大写 <strong>Internet</strong>：全球公用互联网</li><li>小写 <strong>internet</strong>：企业 &#x2F; 内网（私网）</li></ul></li><li>特点：长期迭代、全球共建、极度复杂、高度开放</li></ul><hr>        <h2 id="三、核心要素：协议（Protocol）"   >          <a href="#三、核心要素：协议（Protocol）" class="heading-link"><i class="fas fa-link"></i></a><a href="#三、核心要素：协议（Protocol）" class="headerlink" title="三、核心要素：协议（Protocol）"></a>三、核心要素：协议（Protocol）</h2>              <h3 id="1-协议是什么"   >          <a href="#1-协议是什么" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-协议是什么" class="headerlink" title="1. 协议是什么"></a>1. 协议是什么</h3>      <ul><li>对等层实体在通信时<strong>必须遵守的规则集合</strong></li><li>是网络设备能<strong>互通</strong>的根本保证</li></ul>        <h3 id="2-协议三要素"   >          <a href="#2-协议三要素" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-协议三要素" class="headerlink" title="2. 协议三要素"></a>2. 协议三要素</h3>      <ol><li><strong>语法</strong>：报文格式、长度、字段结构</li><li><strong>语义</strong>：字段含义、代表什么意义、做什么动作</li><li><strong>时序</strong>：通信顺序、触发条件、先后逻辑</li></ol>        <h3 id="3-协议的作用"   >          <a href="#3-协议的作用" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-协议的作用" class="headerlink" title="3. 协议的作用"></a>3. 协议的作用</h3>      <ul><li>实现<strong>互操作性</strong>：不同厂商设备可以互通</li><li>标准来源：<strong>IETF → RFC 文档</strong>（开放、公开）</li></ul>        <h3 id="4-典型协议"   >          <a href="#4-典型协议" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-典型协议" class="headerlink" title="4. 典型协议"></a>4. 典型协议</h3>      <ul><li>网络层：IP</li><li>传输层：TCP、UDP</li><li>应用层：HTTP、DNS 等</li></ul><hr>        <h2 id="四、网络核心思想：分层体系结构"   >          <a href="#四、网络核心思想：分层体系结构" class="heading-link"><i class="fas fa-link"></i></a><a href="#四、网络核心思想：分层体系结构" class="headerlink" title="四、网络核心思想：分层体系结构"></a>四、网络核心思想：分层体系结构</h2>              <h3 id="1-为什么分层"   >          <a href="#1-为什么分层" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-为什么分层" class="headerlink" title="1. 为什么分层"></a>1. 为什么分层</h3>      <ul><li>把<strong>复杂问题拆解</strong>，每层只做一件事</li><li>下层为上层提供服务，上层依赖下层</li></ul>        <h3 id="2-五层核心作用（极简理解）"   >          <a href="#2-五层核心作用（极简理解）" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-五层核心作用（极简理解）" class="headerlink" title="2. 五层核心作用（极简理解）"></a>2. 五层核心作用（极简理解）</h3>      <ol><li>物理层<ul><li>传信号：电磁波、光信号</li></ul></li><li>数据链路层<ul><li>相邻节点<strong>点到点</strong>传输（帧）</li></ul></li><li>网络层<ul><li>主机 ↔ 主机<strong>端到端</strong>传输</li><li>IP：尽力而为、不可靠</li></ul></li><li>传输层<ul><li>进程 ↔ 进程通信</li><li>TCP：可靠；UDP：无连接、快</li></ul></li><li>应用层<ul><li>实现具体应用：网页、游戏、支付、直播、文件传输</li></ul></li></ol>        <h3 id="3-分层思想总结"   >          <a href="#3-分层思想总结" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-分层思想总结" class="headerlink" title="3. 分层思想总结"></a>3. 分层思想总结</h3>      <ul><li>下层支撑上层</li><li>对等层用协议通信</li><li>逐层增强服务、逐步靠近应用</li></ul><hr>        <h2 id="六、互联网的两种理解视角"   >          <a href="#六、互联网的两种理解视角" class="heading-link"><i class="fas fa-link"></i></a><a href="#六、互联网的两种理解视角" class="headerlink" title="六、互联网的两种理解视角"></a>六、互联网的两种理解视角</h2>              <h3 id="1-构成视角（硬件-协议）"   >          <a href="#1-构成视角（硬件-协议）" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-构成视角（硬件-协议）" class="headerlink" title="1. 构成视角（硬件 + 协议）"></a>1. 构成视角（硬件 + 协议）</h3>      <ul><li>主机、交换设备、链路、协议</li><li>由无数网络互联而成：<strong>网络的网络</strong></li></ul>        <h3 id="2-服务视角（应用-基础设施）"   >          <a href="#2-服务视角（应用-基础设施）" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-服务视角（应用-基础设施）" class="headerlink" title="2. 服务视角（应用 + 基础设施）"></a>2. 服务视角（应用 + 基础设施）</h3>      <ul><li><strong>分布式应用进程</strong>：网络存在的目的</li><li><strong>通信基础设施</strong>：为应用提供服务</li><li>接口：<strong>Socket API</strong></li><li>服务类型<ul><li>面向连接：TCP</li><li>无连接：UDP</li></ul></li></ul><hr>        <h2 id="七、必须掌握的核心思想"   >          <a href="#七、必须掌握的核心思想" class="heading-link"><i class="fas fa-link"></i></a><a href="#七、必须掌握的核心思想" class="headerlink" title="七、必须掌握的核心思想"></a>七、必须掌握的核心思想</h2>      <ol><li><strong>网络 &#x3D; 节点 + 边</strong></li><li><strong>计算机网络 &#x3D; 主机 + 交换节点 + 链路 + 协议</strong></li><li><strong>Internet &#x3D; 网络的网络，以 TCP&#x2F;IP 为核心</strong></li><li><strong>协议 &#x3D; 通信规则，是互通的基础</strong></li><li><strong>分层 &#x3D; 拆解复杂网络的唯一正确思路</strong></li><li><strong>网络为应用服务，应用是网络的价值</strong></li></ol>]]></content>
      
      
      <categories>
          
          <category> csdiy实验 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> 操作系统 </tag>
            
            <tag> csdiy </tag>
            
            <tag> 计网 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>CS162笔记第一章（操作系统）</title>
      <link href="/2026/03/18/CS162/"/>
      <url>/2026/03/18/CS162/</url>
      
        <content type="html"><![CDATA[<p>由于我最近在学习学校开设的操作系统课程，想对此有更深入的了解，所以选择了cs162。一来是学习国内外对于学习的两种思维模式，二来是鞭策自己尽早习惯英文环境。鉴于英文授课对很多新手来说并不友好，我在此做出关键内容的整理和课件的搬运与翻译。</p><p>这里推荐两个资源</p><p><span class="exturl"><a class="exturl__link"   href="https://www.bilibili.com/video/BV1MwDSYWEKy/?spm_id_from=333.337.search-card.all.click&vd_source=6f3b9bab813c14ca00fbb56363a43d7e" >【CS162精翻·英文原声】伯克利大学《计算机操作系统》(2020)_哔哩哔哩_bilibili</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p><p><span class="exturl"><a class="exturl__link"   href="https://blog.csdn.net/wizardforcel/article/details/143933530" >UCB CS162 操作系统笔记（一）-CSDN博客</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p><p>这个CSDN上的笔记是所有字幕整理成了文字，我习惯先阅读我要学习的部分，然后再去看一遍视频，接着做笔记的时候再次阅读（仅供参考）</p><p>总课程有二十五章，每章约90min左右，当然我想想要吃透是需要3h的。我会在一月内尽量完成这门课的学习。（立flag）</p>        <h2 id="一、时延引入：操作系统是系统运行的核心"   >          <a href="#一、时延引入：操作系统是系统运行的核心" class="heading-link"><i class="fas fa-link"></i></a><a href="#一、时延引入：操作系统是系统运行的核心" class="headerlink" title="一、时延引入：操作系统是系统运行的核心"></a>一、时延引入：操作系统是系统运行的核心</h2>      <p>课程开篇通过经典的<strong>Jeff Dean计算机时延对照表</strong>，直观展现不同硬件操作的时间量级差异，从纳秒级的缓存访问到毫秒级的跨洋网络传输，时间跨度极大。而能让这些差异巨大的硬件协同工作、支撑上层应用稳定运行的关键，就是<strong>操作系统</strong>。</p><blockquote><p>[!NOTE]</p><p><strong>核心结论</strong>：没有操作系统，无法高效、安全地使用硬件资源；操作系统为应用和程序员屏蔽硬件差异，提供<strong>统一抽象接口</strong>，是连接应用与硬件的关键中间层。</p></blockquote>        <h3 id="经典计算机时延对照表"   >          <a href="#经典计算机时延对照表" class="heading-link"><i class="fas fa-link"></i></a><a href="#经典计算机时延对照表" class="headerlink" title="经典计算机时延对照表"></a>经典计算机时延对照表</h3>      <div class="table-container"><table><thead><tr><th align="left">操作</th><th align="left">英文原文</th><th align="left">时延（纳秒 ns）</th><th align="left">直观量级</th></tr></thead><tbody><tr><td align="left">L1 缓存访问</td><td align="left">L1 cache reference</td><td align="left">0.5 ns</td><td align="left">纳秒级（CPU 内部最快）</td></tr><tr><td align="left">分支预测错误</td><td align="left">Branch mispredict</td><td align="left">5 ns</td><td align="left">纳秒级</td></tr><tr><td align="left">L2 缓存访问</td><td align="left">L2 cache reference</td><td align="left">7 ns</td><td align="left">纳秒级</td></tr><tr><td align="left">互斥锁加锁 &#x2F; 解锁</td><td align="left">Mutex lock&#x2F;unlock</td><td align="left">25 ns</td><td align="left">纳秒级</td></tr><tr><td align="left">主存访问</td><td align="left">Main memory reference</td><td align="left">100 ns</td><td align="left">百纳秒级</td></tr><tr><td align="left">用 Zippy 压缩 1KB 数据</td><td align="left">Compress 1K bytes with Zippy</td><td align="left">3,000 ns</td><td align="left">微秒级（3µs）</td></tr><tr><td align="left">在 1Gbps 网络发送 2KB 数据</td><td align="left">Send 2K bytes over 1 Gbps network</td><td align="left">20,000 ns</td><td align="left">微秒级（20µs）</td></tr><tr><td align="left">从内存顺序读取 1MB</td><td align="left">Read 1 MB sequentially from memory</td><td align="left">250,000 ns</td><td align="left">百微秒级（0.25ms）</td></tr><tr><td align="left">同数据中心内往返</td><td align="left">Round trip within same datacenter</td><td align="left">500,000 ns</td><td align="left">半毫秒级（0.5ms）</td></tr><tr><td align="left">磁盘寻道</td><td align="left">Disk seek</td><td align="left">10,000,000 ns</td><td align="left">10 毫秒级</td></tr><tr><td align="left">从磁盘顺序读取 1MB</td><td align="left">Read 1 MB sequentially from disk</td><td align="left">20,000,000 ns</td><td align="left">20 毫秒级</td></tr><tr><td align="left">数据包往返加州→荷兰→加州</td><td align="left">Send packet CA→Netherlands→CA</td><td align="left">150,000,000 ns</td><td align="left">150 毫秒级</td></tr></tbody></table></div><p>操作系统的核心作用：<strong>管理多应用间的资源共享，处理系统安全问题</strong>，本学期核心学习的构建模块包括进程、线程、并发、调度、协调、地址空间、保护与安全等。</p>        <h2 id="二、日常案例：手机搜索背后的系统逻辑"   >          <a href="#二、日常案例：手机搜索背后的系统逻辑" class="heading-link"><i class="fas fa-link"></i></a><a href="#二、日常案例：手机搜索背后的系统逻辑" class="headerlink" title="二、日常案例：手机搜索背后的系统逻辑"></a>二、日常案例：手机搜索背后的系统逻辑</h2>      <p>通过日常手机搜索场景，直观展现操作系统核心模块的实际落地与协同，理解系统底层组件的整合逻辑：</p><p><strong>完整流程</strong>：手机发起搜索 → 连接DNS服务 → 解析域名获取IP → 访问对应数据中心 → 负载均衡器分配后端服务器 → 服务器执行搜索、生成结果与广告 → 结果原路返回手机</p>        <h3 id="1-DNS（域名系统）详解"   >          <a href="#1-DNS（域名系统）详解" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-DNS（域名系统）详解" class="headerlink" title="1. DNS（域名系统）详解"></a>1. DNS（域名系统）详解</h3>      <p><strong>定义</strong>：Domain Name System，全球分布式、层级化的域名解析系统，核心功能是将人类可读的域名（如baidu.com），翻译为计算机可识别的IP地址，实现域名与IP地址的相互转换。</p><ul><li><strong>层级架构</strong>：树状结构，分为根域名服务器、顶级域服务器（com&#x2F;cn&#x2F;org）、权威域名服务器，每层仅负责自身管辖范围，不存储全量数据</li><li><strong>分布式特性</strong>：无单台服务器存储全球所有域名，每台服务器仅负责局部数据，查询时逐级请求</li><li><strong>缓存机制</strong>：解析结果会缓存，TTL（过期时间）控制缓存时效，大幅提升解析速度，是DNS高性能的关键</li><li><strong>网络协议</strong>：默认使用UDP 53端口，速度快、无连接，适合小型查询；大型请求切换为TCP协议</li></ul>        <h3 id="2-负载均衡器（LB）详解"   >          <a href="#2-负载均衡器（LB）详解" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-负载均衡器（LB）详解" class="headerlink" title="2. 负载均衡器（LB）详解"></a>2. 负载均衡器（LB）详解</h3>      <p><strong>定义</strong>：Load Balancer，数据中心入口的流量调度组件，相当于网络流量的交通警察。</p><ul><li><strong>核心作用</strong>：将用户请求均匀分发至多台后端服务器，避免单台服务器过载，实现高并发承载与高可用</li><li><strong>工作逻辑</strong>：检测后端服务器负载状态，选择空闲服务器转发请求，服务器处理完成后，将结果回传给用户</li></ul>        <h3 id="延伸问题：DNS服务器的一致性与安全性"   >          <a href="#延伸问题：DNS服务器的一致性与安全性" class="heading-link"><i class="fas fa-link"></i></a><a href="#延伸问题：DNS服务器的一致性与安全性" class="headerlink" title="延伸问题：DNS服务器的一致性与安全性"></a>延伸问题：DNS服务器的一致性与安全性</h3>      <ol><li><strong>多DNS服务器如何保持数据一致？</strong> 采用树形层级架构，每层仅管理自身权限范围内的数据；域名更新时，先修改权威服务器，再逐级向上通知刷新；依靠TTL缓存过期机制，实现<strong>最终一致性</strong>，无需实时强同步，兼顾效率与稳定性。</li><li><strong>为什么难以入侵DNS系统？</strong> 物理层面：服务器全球分散部署，跨国家、跨运营商，无法同时攻破；逻辑层面：层级隔离，单台服务器被入侵仅影响局部数据；技术层面：默认53端口严格管控，配合TSIG事务签名、DNSSEC数字签名，防止数据伪造与劫持。</li></ol>        <h2 id="三、操作系统的定义"   >          <a href="#三、操作系统的定义" class="heading-link"><i class="fas fa-link"></i></a><a href="#三、操作系统的定义" class="headerlink" title="三、操作系统的定义"></a>三、操作系统的定义</h2>      <p>目前操作系统<strong>无统一公认的定义</strong>，课程中给出核心界定：</p><p>操作系统包含<strong>内核（Kernel）<strong>与配套程序，其中</strong>内核是计算机中始终运行的核心程序</strong>，其余内容要么是随系统发布的系统程序，要么是用户使用的应用程序。</p>        <h2 id="四、拆解“操作”与“系统”"   >          <a href="#四、拆解“操作”与“系统”" class="heading-link"><i class="fas fa-link"></i></a><a href="#四、拆解“操作”与“系统”" class="headerlink" title="四、拆解“操作”与“系统”"></a>四、拆解“操作”与“系统”</h2>              <h3 id="1-什么是系统（System）"   >          <a href="#1-什么是系统（System）" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-什么是系统（System）" class="headerlink" title="1. 什么是系统（System）"></a>1. 什么是系统（System）</h3>      <p>系统由<strong>多个相互关联的硬件部件</strong>组成，部件之间相互交互、相互依赖；系统追求<strong>鲁棒性（Robustness）</strong>，需要具备完善的错误处理机制，防范恶意操作与误操作，正视硬件的局限性与故障风险，并非简单的硬件拼接。</p>        <h3 id="2-什么是操作（Operating）"   >          <a href="#2-什么是操作（Operating）" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-什么是操作（Operating）" class="headerlink" title="2. 什么是操作（Operating）"></a>2. 什么是操作（Operating）</h3>      <p>“操作”核心是对系统资源的管控，包含三大核心：</p><ul><li><strong>资源共享</strong>：协调多应用竞争CPU、内存、磁盘、网络等硬件资源</li><li><strong>隔离与保护</strong>：实现进程间的权限隔离，单个程序崩溃不影响整个系统，防止非法访问</li><li><strong>多路复用&#x2F;并发</strong>：单CPU硬件基础上，通过快速切换任务，实现多任务同时运行的效果</li></ul>        <h3 id="3-硬件与软件的接口：虚拟化核心"   >          <a href="#3-硬件与软件的接口：虚拟化核心" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-硬件与软件的接口：虚拟化核心" class="headerlink" title="3. 硬件与软件的接口：虚拟化核心"></a>3. 硬件与软件的接口：虚拟化核心</h3>      <p>硬件与软件的接口问题，本质就是<strong>虚拟化问题</strong>。上层应用直接运行在复杂杂乱的硬件上，无法实现受控、安全、统一的访问，课程默认学习者已完成CS61C学习，掌握计算机硬件基础组成：</p><ul><li><strong>处理器（CPU）</strong>：包含寄存器，可存储数据、内存地址，支持进程切换时的状态保存与恢复</li><li><strong>内存</strong>：存储各类数据，部分内存专属操作系统使用，不同区域对应不同进程，实现进程隔离</li><li><strong>缓存</strong>：位于CPU与内存之间，加速数据访问，提升系统处理速度</li><li><strong>页表</strong>：实现虚拟地址到物理地址的转换，支撑虚拟内存功能</li><li><strong>外部设备</strong>：存储设备、网络设备、显示器、GPU等，通过总线与控制器连接，实现硬件协同</li></ul><p>硬件本身复杂度极高，指令集架构（ISA）仅提供基础标准化，仍无法满足便捷编程的需求，<strong>操作系统的核心价值，就是将底层硬件细节全部抽象，提供干净的边界与虚拟化视图，大幅降低应用编程难度</strong>。</p>        <h2 id="五、操作系统的核心：抽象与虚拟化（幻觉性质）"   >          <a href="#五、操作系统的核心：抽象与虚拟化（幻觉性质）" class="heading-link"><i class="fas fa-link"></i></a><a href="#五、操作系统的核心：抽象与虚拟化（幻觉性质）" class="headerlink" title="五、操作系统的核心：抽象与虚拟化（幻觉性质）"></a>五、操作系统的核心：抽象与虚拟化（幻觉性质）</h2>      <p>操作系统最核心的特性是<strong>幻觉性质（Illusion）</strong>，即通过虚拟化技术，为上层应用提供硬件本身不存在、却简洁易用的<strong>抽象接口</strong>，让应用误以为独占硬件资源，无需关注底层硬件的复杂性。</p>        <h3 id="1-核心抽象内容（硬件中不存在，由操作系统创造）"   >          <a href="#1-核心抽象内容（硬件中不存在，由操作系统创造）" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-核心抽象内容（硬件中不存在，由操作系统创造）" class="headerlink" title="1. 核心抽象内容（硬件中不存在，由操作系统创造）"></a>1. 核心抽象内容（硬件中不存在，由操作系统创造）</h3>      <ul><li><strong>线程</strong>：虚拟化CPU，将单个物理CPU转化为多个可独立运行的执行单元，实现并发</li><li><strong>地址空间（虚拟内存）</strong>：虚拟化物理内存，为每个进程提供独立、连续、受保护的内存视图，营造“无限内存”的幻觉</li><li><strong>文件</strong>：虚拟化磁盘块，将硬件层面零散的存储块，封装为易用的文件与目录，实现持久化存储</li><li><strong>用户与权限</strong>：创造用户概念，实现系统权限管控，保障系统安全</li><li><strong>套接字&#x2F;消息队列</strong>：虚拟化网络传输，将不可靠的网络数据包，转化为可靠、有序的通信接口</li></ul>        <h3 id="2-虚拟化模型"   >          <a href="#2-虚拟化模型" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-虚拟化模型" class="headerlink" title="2. 虚拟化模型"></a>2. 虚拟化模型</h3>      <p>操作系统运行在硬件之上，作为核心中间层，将底层杂乱的硬件资源，转化为标准化、易用的运行环境，应用程序不直接接触硬件，仅与操作系统提供的抽象交互。</p>        <h2 id="六、关键概念：程序与进程"   >          <a href="#六、关键概念：程序与进程" class="heading-link"><i class="fas fa-link"></i></a><a href="#六、关键概念：程序与进程" class="headerlink" title="六、关键概念：程序与进程"></a>六、关键概念：程序与进程</h2>              <h3 id="1-进程的定义"   >          <a href="#1-进程的定义" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-进程的定义" class="headerlink" title="1. 进程的定义"></a>1. 进程的定义</h3>      <p><strong>进程</strong>是操作系统提供的、具备<strong>受限权限的执行环境</strong>，相当于一个干净的运行容器，是应用程序实际运行的载体，也是操作系统虚拟化的核心产物。</p>        <h3 id="2-进程包含的核心内容"   >          <a href="#2-进程包含的核心内容" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-进程包含的核心内容" class="headerlink" title="2. 进程包含的核心内容"></a>2. 进程包含的核心内容</h3>      <ul><li>独立的地址空间（受保护的内存块）</li><li>一个或多个线程（执行单元）</li><li>打开的文件、网络套接字</li></ul>        <h3 id="3-程序与进程的区别"   >          <a href="#3-程序与进程的区别" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-程序与进程的区别" class="headerlink" title="3. 程序与进程的区别"></a>3. 程序与进程的区别</h3>      <ul><li><strong>程序</strong>：磁盘上存储的二进制代码文件，是静态、未运行的状态</li><li><strong>进程</strong>：程序被实例化、加载运行后的动态状态，是操作系统分配资源的基本单位</li></ul><p><strong>核心结论</strong>：应用程序感知到的“机器”，并非真实物理硬件，而是操作系统提供的<strong>进程抽象</strong>；每个运行的程序对应独立进程，进程提供的接口远比原始硬件简洁易用。</p>        <h2 id="七、操作系统的三大核心角色（必考）"   >          <a href="#七、操作系统的三大核心角色（必考）" class="heading-link"><i class="fas fa-link"></i></a><a href="#七、操作系统的三大核心角色（必考）" class="headerlink" title="七、操作系统的三大核心角色（必考）"></a>七、操作系统的三大核心角色（必考）</h2>              <h3 id="1-裁判（Referee）"   >          <a href="#1-裁判（Referee）" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-裁判（Referee）" class="headerlink" title="1. 裁判（Referee）"></a>1. 裁判（Referee）</h3>      <p>作为系统资源的管理者，负责CPU、内存、设备等资源的分配与调度，实现进程间的隔离、保护与公平竞争，处理权限与安全问题，避免资源争抢与系统崩溃。</p>        <h3 id="2-幻术师-抽象大师（Illusionist）"   >          <a href="#2-幻术师-抽象大师（Illusionist）" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-幻术师-抽象大师（Illusionist）" class="headerlink" title="2. 幻术师&#x2F;抽象大师（Illusionist）"></a>2. 幻术师&#x2F;抽象大师（Illusionist）</h3>      <p>通过虚拟化技术，为应用制造独占硬件、资源无限的幻觉，屏蔽硬件差异与底层细节，提供进程、线程、地址空间、文件等高层抽象，让编程更简单。</p>        <h3 id="3-粘合剂（Glue）"   >          <a href="#3-粘合剂（Glue）" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-粘合剂（Glue）" class="headerlink" title="3. 粘合剂（Glue）"></a>3. 粘合剂（Glue）</h3>      <p>作为软硬件生态的连接层，提供统一的存储、网络、设备访问接口，将零散的硬件、驱动、应用粘合在一起，实现跨硬件、跨平台的兼容运行。</p>        <h2 id="第一讲核心总结"   >          <a href="#第一讲核心总结" class="heading-link"><i class="fas fa-link"></i></a><a href="#第一讲核心总结" class="headerlink" title="第一讲核心总结"></a>第一讲核心总结</h2>      <ol><li>操作系统是硬件与应用之间的中间层，核心是<strong>虚拟化+抽象</strong>，解决硬件复杂性问题</li><li>内核是操作系统始终运行的核心，负责资源管理与抽象提供</li><li>进程是应用运行的核心载体，程序是静态代码，进程是动态运行实例</li><li>操作系统兼具裁判、幻术师、粘合剂三大角色，实现资源共享、隔离保护、便捷编程三大目标</li></ol>]]></content>
      
      
      <categories>
          
          <category> csdiy实验 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> cs162 </tag>
            
            <tag> 操作系统 </tag>
            
            <tag> csdiy </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>天梯赛合集</title>
      <link href="/2026/03/13/%E5%A4%A9%E6%A2%AF%E8%B5%9B/"/>
      <url>/2026/03/13/%E5%A4%A9%E6%A2%AF%E8%B5%9B/</url>
      
        <content type="html"><![CDATA[<p>临时抱佛脚中，可能已经两三个月不写代码了。要比赛了其实有些担心。但是没有关系，成绩不好也没关系，因为我一定下次会更好。我应当取得的成绩是一定会得到的。现在是临时抱佛脚的总结。</p><p>接下来我会把题目按照三个等级整理，L1,L2,L3</p>        <h1 id="L1"   >          <a href="#L1" class="heading-link"><i class="fas fa-link"></i></a><a href="#L1" class="headerlink" title="L1"></a>L1</h1>              <h2 id="L1-5-这是字符串题"   >          <a href="#L1-5-这是字符串题" class="heading-link"><i class="fas fa-link"></i></a><a href="#L1-5-这是字符串题" class="headerlink" title="L1-5 这是字符串题"></a><strong>L1-5 这是字符串题</strong></h2>      <p><img src="/../images/image-20260313230850389.png" alt="image-20260313230850389"></p><p>其实就是一个映射题目啦，第一个输入用string读入，第二个输入对应的是第i个字母的美观值。那直接用一个数组存。要求计算第i个小写字母出现了多少次，用一个数组来计数，把字母映射为字母的数字顺序（s[i]-‘a’+1）。得分就是两个映射，先映射为数字，再用美观值数组映射美观值。代码附上</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">int</span> ch[<span class="number">10000</span>];</span><br><span class="line"><span class="type">int</span> ans[<span class="number">10000</span>];</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">solve</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    string s;</span><br><span class="line">    <span class="type">int</span> sum = <span class="number">0</span>;</span><br><span class="line">    cin &gt;&gt; s;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= <span class="number">26</span>; i++) &#123;</span><br><span class="line">        <span class="type">int</span> x;</span><br><span class="line">        cin &gt;&gt; x;</span><br><span class="line">        ch[i] = x;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; s.<span class="built_in">size</span>(); i++) &#123;</span><br><span class="line">        sum += ch[s[i] - <span class="string">&#x27;a&#x27;</span> + <span class="number">1</span>];</span><br><span class="line">        ans[s[i] - <span class="string">&#x27;a&#x27;</span> + <span class="number">1</span>]++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= <span class="number">26</span>; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span>(i==<span class="number">26</span>)&#123;</span><br><span class="line">            cout &lt;&lt;ans[i];</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span>&#123;</span><br><span class="line">           cout &lt;&lt; ans[i] &lt;&lt; <span class="string">&quot; &quot;</span>; </span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">    &#125;</span><br><span class="line">    cout &lt;&lt; endl</span><br><span class="line">         &lt;&lt; sum;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    ios::<span class="built_in">sync_with_stdio</span>(<span class="literal">false</span>);</span><br><span class="line">    cin.<span class="built_in">tie</span>(<span class="literal">nullptr</span>);</span><br><span class="line">    <span class="built_in">solve</span>();</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="L1-7-大幂数"   >          <a href="#L1-7-大幂数" class="heading-link"><i class="fas fa-link"></i></a><a href="#L1-7-大幂数" class="headerlink" title="L1-7 大幂数"></a><strong>L1-7 大幂数</strong></h2>      <p><img src="/../images/image-20260313232345212.png" alt="image-20260313232345212"></p><p>当你试图寻找某些规律时，就会发现没有规律，所以这道题只能枚举了。暴力呢，也要有策略的暴力，这道题是有两个变量的，底数个数和幂k。因为k越大，枚举项数越小，而且k有上限31，所以从31开始从大到小遍历。如果内层遍历项数的循环大于所给数了，break掉这层循环开始尝试下一个k。</p><p>但是这里涉及时间的问题，是的我们需要用到快速幂。</p><p>补一下快速幂模板，这是原理</p><p><img src="/../images/image-20260313233639524.png" alt="image-20260313233639524"></p><p>这是代码</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">long</span> <span class="type">long</span> <span class="title">fast_pow</span><span class="params">(<span class="type">long</span> <span class="type">long</span> base, <span class="type">int</span> exp)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="type">long</span> <span class="type">long</span> result = <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span> (exp &gt; <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">if</span> (exp &amp; <span class="number">1</span>)</span><br><span class="line">            result *= base;</span><br><span class="line">        base *= base;</span><br><span class="line">        exp &gt;&gt;= <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>但是呢你用这个写就会wa。为什么呢</p><ul><li>i&#x3D;100, k&#x3D;10 → 100^10 ≈ 10^20，已经超过 long long 最大值。</li></ul><p>但我们真正关心的是：<code>i^k</code> 是否已经超过 n。如果 <code>i^k &gt; n</code>，那么 <code>sum = 1^k + 2^k + ... + i^k</code> 一定大于 n（因为所有项都是正数），所以我们可以提前停止循环，不需要继续计算更大的 i。</p><p>所以我们进行一个剪枝</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">long</span> <span class="type">long</span> <span class="title">safe_pow</span><span class="params">(<span class="type">long</span> <span class="type">long</span> base, <span class="type">int</span> exp, <span class="type">long</span> <span class="type">long</span> limit)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="type">long</span> <span class="type">long</span> result = <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; exp; ++i) &#123;</span><br><span class="line">        <span class="keyword">if</span> (limit / base &lt; result) &#123;</span><br><span class="line">            <span class="keyword">return</span> limit + <span class="number">1</span>;   <span class="comment">// 表示幂结果已经超过 limit</span></span><br><span class="line">        &#125;</span><br><span class="line">        result *= base;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>ok，附上完整代码</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">long</span> <span class="type">long</span> <span class="title">safe_pow</span><span class="params">(<span class="type">long</span> <span class="type">long</span> base, <span class="type">int</span> exp, <span class="type">long</span> <span class="type">long</span> limit)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="type">long</span> <span class="type">long</span> result = <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; exp; ++i) &#123;</span><br><span class="line">        <span class="keyword">if</span> (limit / base &lt; result) &#123;</span><br><span class="line">            <span class="keyword">return</span> limit + <span class="number">1</span>;   <span class="comment">// 表示幂结果已经超过 limit</span></span><br><span class="line">        &#125;</span><br><span class="line">        result *= base;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">solve</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="type">long</span> <span class="type">long</span> n;</span><br><span class="line">    cin &gt;&gt; n;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> k = <span class="number">30</span>; k &gt;= <span class="number">1</span>; k--) &#123;</span><br><span class="line">        <span class="type">long</span> <span class="type">long</span> sum = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>;; i++) &#123;</span><br><span class="line">            <span class="type">long</span> <span class="type">long</span> power = <span class="built_in">safe_pow</span>(i, k, n);</span><br><span class="line">            sum += power;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (sum == n) &#123;</span><br><span class="line">                <span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">1</span>; j &lt;= i; j++) &#123;</span><br><span class="line">                    <span class="keyword">if</span> (j &gt; <span class="number">1</span>) cout &lt;&lt; <span class="string">&quot;+&quot;</span>;</span><br><span class="line">                    cout &lt;&lt; j &lt;&lt; <span class="string">&quot;^&quot;</span> &lt;&lt; k;</span><br><span class="line">                &#125;</span><br><span class="line">                cout &lt;&lt; endl;</span><br><span class="line">                <span class="keyword">return</span>;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (sum &gt; n || power &gt; n) &#123;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;Impossible for &quot;</span> &lt;&lt; n &lt;&lt; <span class="string">&quot;.&quot;</span> &lt;&lt; endl;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="built_in">solve</span>();</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="L1-8-现代战争"   >          <a href="#L1-8-现代战争" class="heading-link"><i class="fas fa-link"></i></a><a href="#L1-8-现代战争" class="headerlink" title="L1-8 现代战争"></a><strong>L1-8 现代战争</strong></h2>      <p><img src="/../images/image-20260313235724009.png" alt="image-20260313235724009"></p><p>嗯一道语法题</p><ol><li><strong>数据结构设计</strong><ul><li>使用结构体数组存储每个建筑的位置和价值</li><li>使用row和col数组标记被炸掉的行和列</li></ul></li><li><strong>核心算法流程</strong><ul><li>读取地图数据，同时将所有建筑信息存入结构体数组</li><li>按建筑价值排序（从小到大）</li><li>从大到小选择k个未被炸掉的最高价值建筑进行轰炸</li><li>输出剩余的行和列组成的缩小后地图</li></ul></li></ol><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;algorithm&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;cstring&gt;</span></span></span><br><span class="line"> </span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"> </span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">node</span></span><br><span class="line">&#123;</span><br><span class="line"><span class="type">int</span> x;</span><br><span class="line"><span class="type">int</span> y;</span><br><span class="line"><span class="type">int</span> w;</span><br><span class="line">&#125;nodes[ <span class="number">1000005</span> ];</span><br><span class="line"> </span><br><span class="line"><span class="type">int</span> mp[ <span class="number">1005</span> ][ <span class="number">1005</span> ];</span><br><span class="line"><span class="type">int</span> row[ <span class="number">1005</span> ];</span><br><span class="line"><span class="type">int</span> col[ <span class="number">1005</span> ];</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">cmp</span><span class="params">( node a, node b )</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="keyword">return</span> a.w &lt; b.w;</span><br><span class="line">&#125;</span><br><span class="line"> </span><br><span class="line"><span class="type">int</span> n, m, k;</span><br><span class="line"><span class="type">int</span> length = <span class="number">0</span>;</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span> <span class="params">( )</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"><span class="built_in">memset</span>( row, <span class="number">0</span>, <span class="built_in">sizeof</span> ( row ) );</span><br><span class="line"><span class="built_in">memset</span>( col, <span class="number">0</span>, <span class="built_in">sizeof</span> ( col ) );</span><br><span class="line">cin &gt;&gt; n &gt;&gt; m &gt;&gt; k;</span><br><span class="line"> </span><br><span class="line"><span class="keyword">for</span> ( <span class="type">int</span> i = <span class="number">0</span>; i &lt; n; ++ i )</span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">for</span> ( <span class="type">int</span> j = <span class="number">0</span>; j &lt; m; ++ j )</span><br><span class="line">&#123;</span><br><span class="line">cin &gt;&gt; mp[ i ][ j ];</span><br><span class="line">nodes[ length ].x = i;</span><br><span class="line">nodes[ length ].y = j;</span><br><span class="line">nodes[ length ].w = mp[ i ][ j ];</span><br><span class="line">++ length;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">sort</span> ( nodes, nodes + length, cmp );</span><br><span class="line"> </span><br><span class="line"><span class="type">int</span> x, y;</span><br><span class="line"><span class="keyword">while</span> ( k )</span><br><span class="line">&#123;</span><br><span class="line">-- length;</span><br><span class="line">x = nodes[ length ].x;</span><br><span class="line">y = nodes[ length ].y;</span><br><span class="line"><span class="keyword">if</span> ( row[ x ] || col[ y ] )</span><br><span class="line"><span class="keyword">continue</span>;</span><br><span class="line">++ row[ x ];</span><br><span class="line">++ col[ y ];</span><br><span class="line">-- k;</span><br><span class="line">&#125;</span><br><span class="line">    <span class="type">int</span> flag;</span><br><span class="line"><span class="keyword">for</span> ( <span class="type">int</span> i = <span class="number">0</span>; i &lt; n; ++ i )</span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">if</span> ( row[ i ] )</span><br><span class="line"><span class="keyword">continue</span>;</span><br><span class="line">        flag = <span class="number">1</span>;</span><br><span class="line"><span class="keyword">for</span> ( <span class="type">int</span> j = <span class="number">0</span>; j &lt; m; ++ j )</span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">if</span> ( col[ j ] )</span><br><span class="line"><span class="keyword">continue</span>;</span><br><span class="line">            <span class="keyword">if</span> ( flag )</span><br><span class="line">            &#123;</span><br><span class="line">                cout &lt;&lt; mp[ i ][ j ];</span><br><span class="line">                flag = <span class="number">0</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span></span><br><span class="line">                cout &lt;&lt; <span class="string">&quot; &quot;</span>&lt;&lt; mp[ i ][ j ];</span><br><span class="line">&#125;</span><br><span class="line">cout &lt;&lt; endl;</span><br><span class="line">&#125;</span><br><span class="line"> </span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>map用法</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 1. 不同的定义方式</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">map_definition</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 默认升序 map (按键从小到大)</span></span><br><span class="line">    map&lt;<span class="type">int</span>, string&gt; m1;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 降序 map (按键从大到小)</span></span><br><span class="line">    map&lt;<span class="type">int</span>, string, greater&lt;<span class="type">int</span>&gt;&gt; m2;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 自定义排序规则</span></span><br><span class="line">    <span class="keyword">struct</span> <span class="title class_">cmp</span> &#123;</span><br><span class="line">        <span class="function"><span class="type">bool</span> <span class="title">operator</span><span class="params">()</span><span class="params">(<span class="type">int</span> a, <span class="type">int</span> b)</span> <span class="type">const</span> </span>&#123;</span><br><span class="line">            <span class="keyword">return</span> a % <span class="number">10</span> &lt; b % <span class="number">10</span>;  <span class="comment">// 按个位数排序</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;</span><br><span class="line">    map&lt;<span class="type">int</span>, string, cmp&gt; m3;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 2. 插入元素</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">map_insert</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    map&lt;<span class="type">int</span>, string&gt; m;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 方法1: 使用 [] 操作符 (如果键不存在则创建，存在则修改)</span></span><br><span class="line">    m[<span class="number">1</span>] = <span class="string">&quot;one&quot;</span>;</span><br><span class="line">    m[<span class="number">2</span>] = <span class="string">&quot;two&quot;</span>;</span><br><span class="line">    m[<span class="number">1</span>] = <span class="string">&quot;ONE&quot;</span>;  <span class="comment">// 修改键1的值</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 方法2: 使用 insert (如果键已存在则插入失败)</span></span><br><span class="line">    m.<span class="built_in">insert</span>(&#123;<span class="number">3</span>, <span class="string">&quot;three&quot;</span>&#125;);</span><br><span class="line">    m.<span class="built_in">insert</span>(<span class="built_in">pair</span>&lt;<span class="type">int</span>, string&gt;(<span class="number">4</span>, <span class="string">&quot;four&quot;</span>));</span><br><span class="line">    m.<span class="built_in">insert</span>(<span class="built_in">make_pair</span>(<span class="number">5</span>, <span class="string">&quot;five&quot;</span>));</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 方法3: 批量插入</span></span><br><span class="line">    vector&lt;pair&lt;<span class="type">int</span>, string&gt;&gt; v = &#123;&#123;<span class="number">6</span>, <span class="string">&quot;six&quot;</span>&#125;, &#123;<span class="number">7</span>, <span class="string">&quot;seven&quot;</span>&#125;&#125;;</span><br><span class="line">    m.<span class="built_in">insert</span>(v.<span class="built_in">begin</span>(), v.<span class="built_in">end</span>());</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 3. 访问元素</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">map_access</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    map&lt;<span class="type">int</span>, string&gt; m = &#123;&#123;<span class="number">1</span>, <span class="string">&quot;one&quot;</span>&#125;, &#123;<span class="number">2</span>, <span class="string">&quot;two&quot;</span>&#125;, &#123;<span class="number">3</span>, <span class="string">&quot;three&quot;</span>&#125;&#125;;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 方法1: 使用 [] (如果键不存在会创建)</span></span><br><span class="line">    string s1 = m[<span class="number">1</span>];  <span class="comment">// s1 = &quot;one&quot;</span></span><br><span class="line">    string s2 = m[<span class="number">4</span>];  <span class="comment">// 键4不存在，创建空字符串</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 方法2: 使用 at (如果键不存在会抛出异常)</span></span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">        string s3 = m.<span class="built_in">at</span>(<span class="number">2</span>);  <span class="comment">// s3 = &quot;two&quot;</span></span><br><span class="line">        string s4 = m.<span class="built_in">at</span>(<span class="number">5</span>);  <span class="comment">// 抛出 out_of_range 异常</span></span><br><span class="line">    &#125; <span class="built_in">catch</span> (<span class="type">const</span> out_of_range&amp; e) &#123;</span><br><span class="line">        cout &lt;&lt; <span class="string">&quot;键不存在&quot;</span> &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 方法3: 使用 find (安全访问，不创建新元素)</span></span><br><span class="line">    <span class="keyword">auto</span> it = m.<span class="built_in">find</span>(<span class="number">3</span>);</span><br><span class="line">    <span class="keyword">if</span> (it != m.<span class="built_in">end</span>()) &#123;</span><br><span class="line">        cout &lt;&lt; <span class="string">&quot;找到: &quot;</span> &lt;&lt; it-&gt;first &lt;&lt; <span class="string">&quot; -&gt; &quot;</span> &lt;&lt; it-&gt;second &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 4. 遍历元素</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">map_traversal</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    map&lt;<span class="type">int</span>, string&gt; m = &#123;&#123;<span class="number">1</span>, <span class="string">&quot;one&quot;</span>&#125;, &#123;<span class="number">2</span>, <span class="string">&quot;two&quot;</span>&#125;, &#123;<span class="number">3</span>, <span class="string">&quot;three&quot;</span>&#125;&#125;;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 方法1: 范围for循环 (C++11)</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">const</span> <span class="keyword">auto</span>&amp; p : m) &#123;</span><br><span class="line">        cout &lt;&lt; p.first &lt;&lt; <span class="string">&quot; : &quot;</span> &lt;&lt; p.second &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 方法2: 迭代器遍历</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">auto</span> it = m.<span class="built_in">begin</span>(); it != m.<span class="built_in">end</span>(); ++it) &#123;</span><br><span class="line">        cout &lt;&lt; it-&gt;first &lt;&lt; <span class="string">&quot; : &quot;</span> &lt;&lt; it-&gt;second &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 方法3: 反向遍历 (从大到小)</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">auto</span> it = m.<span class="built_in">rbegin</span>(); it != m.<span class="built_in">rend</span>(); ++it) &#123;</span><br><span class="line">        cout &lt;&lt; it-&gt;first &lt;&lt; <span class="string">&quot; : &quot;</span> &lt;&lt; it-&gt;second &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 5. 删除元素</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">map_erase</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    map&lt;<span class="type">int</span>, string&gt; m = &#123;&#123;<span class="number">1</span>, <span class="string">&quot;one&quot;</span>&#125;, &#123;<span class="number">2</span>, <span class="string">&quot;two&quot;</span>&#125;, &#123;<span class="number">3</span>, <span class="string">&quot;three&quot;</span>&#125;, &#123;<span class="number">4</span>, <span class="string">&quot;four&quot;</span>&#125;&#125;;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 方法1: 按键删除</span></span><br><span class="line">    m.<span class="built_in">erase</span>(<span class="number">2</span>);  <span class="comment">// 删除键为2的元素</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 方法2: 用迭代器删除</span></span><br><span class="line">    <span class="keyword">auto</span> it = m.<span class="built_in">find</span>(<span class="number">3</span>);</span><br><span class="line">    <span class="keyword">if</span> (it != m.<span class="built_in">end</span>()) &#123;</span><br><span class="line">        m.<span class="built_in">erase</span>(it);  <span class="comment">// 删除迭代器指向的元素</span></span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 方法3: 删除范围内的元素</span></span><br><span class="line">    <span class="keyword">auto</span> start = m.<span class="built_in">find</span>(<span class="number">1</span>);</span><br><span class="line">    <span class="keyword">auto</span> end = m.<span class="built_in">find</span>(<span class="number">4</span>);</span><br><span class="line">    <span class="keyword">if</span> (start != m.<span class="built_in">end</span>() &amp;&amp; end != m.<span class="built_in">end</span>()) &#123;</span><br><span class="line">        m.<span class="built_in">erase</span>(start, end);  <span class="comment">// 删除从start到end(不包括end)的元素</span></span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 方法4: 清空所有元素</span></span><br><span class="line">    m.<span class="built_in">clear</span>();  <span class="comment">// 删除所有元素</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 6. 查找和统计</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">map_find</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    map&lt;<span class="type">int</span>, string&gt; m = &#123;&#123;<span class="number">1</span>, <span class="string">&quot;one&quot;</span>&#125;, &#123;<span class="number">2</span>, <span class="string">&quot;two&quot;</span>&#125;, &#123;<span class="number">3</span>, <span class="string">&quot;three&quot;</span>&#125;&#125;;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// find: 查找键，返回迭代器</span></span><br><span class="line">    <span class="keyword">auto</span> it = m.<span class="built_in">find</span>(<span class="number">2</span>);</span><br><span class="line">    <span class="keyword">if</span> (it != m.<span class="built_in">end</span>()) &#123;</span><br><span class="line">        cout &lt;&lt; <span class="string">&quot;找到键2，值为: &quot;</span> &lt;&lt; it-&gt;second &lt;&lt; endl;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        cout &lt;&lt; <span class="string">&quot;未找到键2&quot;</span> &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// count: 统计键出现的次数 (对于map只能是0或1)</span></span><br><span class="line">    <span class="keyword">if</span> (m.<span class="built_in">count</span>(<span class="number">3</span>)) &#123;</span><br><span class="line">        cout &lt;&lt; <span class="string">&quot;键3存在&quot;</span> &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// lower_bound: 返回第一个键 &gt;= 给定键的迭代器</span></span><br><span class="line">    <span class="keyword">auto</span> lb = m.<span class="built_in">lower_bound</span>(<span class="number">2</span>);  <span class="comment">// 指向键2</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// upper_bound: 返回第一个键 &gt; 给定键的迭代器</span></span><br><span class="line">    <span class="keyword">auto</span> ub = m.<span class="built_in">upper_bound</span>(<span class="number">2</span>);  <span class="comment">// 指向键3</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// equal_range: 返回一对迭代器，表示键等于给定值的范围</span></span><br><span class="line">    <span class="keyword">auto</span> range = m.<span class="built_in">equal_range</span>(<span class="number">2</span>);</span><br><span class="line">    <span class="comment">// range.first 指向键2，range.second 指向键3</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 7. 大小和容量</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">map_capacity</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    map&lt;<span class="type">int</span>, string&gt; m = &#123;&#123;<span class="number">1</span>, <span class="string">&quot;one&quot;</span>&#125;, &#123;<span class="number">2</span>, <span class="string">&quot;two&quot;</span>&#125;, &#123;<span class="number">3</span>, <span class="string">&quot;three&quot;</span>&#125;&#125;;</span><br><span class="line">    </span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;大小: &quot;</span> &lt;&lt; m.<span class="built_in">size</span>() &lt;&lt; endl;        <span class="comment">// 3</span></span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;是否为空: &quot;</span> &lt;&lt; m.<span class="built_in">empty</span>() &lt;&lt; endl;   <span class="comment">// 0 (false)</span></span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;最大容量: &quot;</span> &lt;&lt; m.<span class="built_in">max_size</span>() &lt;&lt; endl;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 8. 交换和比较</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">map_swap_compare</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    map&lt;<span class="type">int</span>, string&gt; m1 = &#123;&#123;<span class="number">1</span>, <span class="string">&quot;one&quot;</span>&#125;, &#123;<span class="number">2</span>, <span class="string">&quot;two&quot;</span>&#125;&#125;;</span><br><span class="line">    map&lt;<span class="type">int</span>, string&gt; m2 = &#123;&#123;<span class="number">3</span>, <span class="string">&quot;three&quot;</span>&#125;, &#123;<span class="number">4</span>, <span class="string">&quot;four&quot;</span>&#125;&#125;;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 交换两个map的内容</span></span><br><span class="line">    m<span class="number">1.</span><span class="built_in">swap</span>(m2);</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// map的比较 (按键的顺序)</span></span><br><span class="line">    <span class="keyword">if</span> (m1 &lt; m2) &#123;</span><br><span class="line">        cout &lt;&lt; <span class="string">&quot;m1 &lt; m2&quot;</span> &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 9. 自定义类型作为键</span></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">Student</span> &#123;</span><br><span class="line">    string name;</span><br><span class="line">    <span class="type">int</span> id;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 需要定义比较运算符</span></span><br><span class="line">    <span class="type">bool</span> <span class="keyword">operator</span>&lt;(<span class="type">const</span> Student&amp; other) <span class="type">const</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (name != other.name) <span class="keyword">return</span> name &lt; other.name;</span><br><span class="line">        <span class="keyword">return</span> id &lt; other.id;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">map_custom_key</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    map&lt;Student, <span class="type">int</span>&gt; scores;</span><br><span class="line">    scores[&#123;<span class="string">&quot;Alice&quot;</span>, <span class="number">1001</span>&#125;] = <span class="number">95</span>;</span><br><span class="line">    scores[&#123;<span class="string">&quot;Bob&quot;</span>, <span class="number">1002</span>&#125;] = <span class="number">87</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 10. multimap (允许重复键)</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">multimap_example</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    multimap&lt;<span class="type">int</span>, string&gt; mm;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 插入 (允许重复键)</span></span><br><span class="line">    mm.<span class="built_in">insert</span>(&#123;<span class="number">1</span>, <span class="string">&quot;one&quot;</span>&#125;);</span><br><span class="line">    mm.<span class="built_in">insert</span>(&#123;<span class="number">1</span>, <span class="string">&quot;uno&quot;</span>&#125;);</span><br><span class="line">    mm.<span class="built_in">insert</span>(&#123;<span class="number">2</span>, <span class="string">&quot;two&quot;</span>&#125;);</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 遍历指定键的所有值</span></span><br><span class="line">    <span class="keyword">auto</span> range = mm.<span class="built_in">equal_range</span>(<span class="number">1</span>);</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">auto</span> it = range.first; it != range.second; ++it) &#123;</span><br><span class="line">        cout &lt;&lt; it-&gt;second &lt;&lt; endl;  <span class="comment">// 输出: one, uno</span></span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// count 可能大于1</span></span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;键1出现次数: &quot;</span> &lt;&lt; mm.<span class="built_in">count</span>(<span class="number">1</span>) &lt;&lt; endl;  <span class="comment">// 2</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 11. unordered_map (哈希表，无序，更快)</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">unordered_map_example</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    unordered_map&lt;<span class="type">int</span>, string&gt; um;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 基本操作和map类似，但元素无序</span></span><br><span class="line">    um[<span class="number">1</span>] = <span class="string">&quot;one&quot;</span>;</span><br><span class="line">    um[<span class="number">2</span>] = <span class="string">&quot;two&quot;</span>;</span><br><span class="line">    um[<span class="number">3</span>] = <span class="string">&quot;three&quot;</span>;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 遍历顺序不保证</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">const</span> <span class="keyword">auto</span>&amp; p : um) &#123;</span><br><span class="line">        cout &lt;&lt; p.first &lt;&lt; <span class="string">&quot; : &quot;</span> &lt;&lt; p.second &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 12. 综合示例：统计单词频率</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">word_count</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    vector&lt;string&gt; words = &#123;<span class="string">&quot;apple&quot;</span>, <span class="string">&quot;banana&quot;</span>, <span class="string">&quot;apple&quot;</span>, <span class="string">&quot;orange&quot;</span>, <span class="string">&quot;banana&quot;</span>, <span class="string">&quot;apple&quot;</span>&#125;;</span><br><span class="line">    </span><br><span class="line">    map&lt;string, <span class="type">int</span>&gt; freq;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 统计频率</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">const</span> string&amp; word : words) &#123;</span><br><span class="line">        freq[word]++;  <span class="comment">// 键不存在时自动创建，值为0，然后++</span></span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 按频率从高到低输出</span></span><br><span class="line">    vector&lt;pair&lt;string, <span class="type">int</span>&gt;&gt; <span class="built_in">sorted</span>(freq.<span class="built_in">begin</span>(), freq.<span class="built_in">end</span>());</span><br><span class="line">    <span class="built_in">sort</span>(sorted.<span class="built_in">begin</span>(), sorted.<span class="built_in">end</span>(), </span><br><span class="line">         [](<span class="type">const</span> <span class="keyword">auto</span>&amp; a, <span class="type">const</span> <span class="keyword">auto</span>&amp; b) &#123;</span><br><span class="line">             <span class="keyword">return</span> a.second &gt; b.second;</span><br><span class="line">         &#125;);</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span> (<span class="type">const</span> <span class="keyword">auto</span>&amp; p : sorted) &#123;</span><br><span class="line">        cout &lt;&lt; p.first &lt;&lt; <span class="string">&quot;: &quot;</span> &lt;&lt; p.second &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 调用各种示例函数来测试</span></span><br><span class="line">    <span class="built_in">map_definition</span>();</span><br><span class="line">    <span class="built_in">map_insert</span>();</span><br><span class="line">    <span class="built_in">map_access</span>();</span><br><span class="line">    <span class="built_in">map_traversal</span>();</span><br><span class="line">    <span class="built_in">map_erase</span>();</span><br><span class="line">    <span class="built_in">map_find</span>();</span><br><span class="line">    <span class="built_in">map_capacity</span>();</span><br><span class="line">    <span class="built_in">map_swap_compare</span>();</span><br><span class="line">    <span class="built_in">map_custom_key</span>();</span><br><span class="line">    <span class="built_in">multimap_example</span>();</span><br><span class="line">    <span class="built_in">unordered_map_example</span>();</span><br><span class="line">    <span class="built_in">word_count</span>();</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>vector基本用法</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="comment">// ==================== 1. vector 基本操作 ====================</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">vector_basic</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 1.1 创建和初始化</span></span><br><span class="line">    vector&lt;<span class="type">int</span>&gt; v1;</span><br><span class="line">    <span class="function">vector&lt;<span class="type">int</span>&gt; <span class="title">v2</span><span class="params">(<span class="number">10</span>)</span></span>;</span><br><span class="line">    <span class="function">vector&lt;<span class="type">int</span>&gt; <span class="title">v3</span><span class="params">(<span class="number">10</span>, <span class="number">5</span>)</span></span>;</span><br><span class="line">    vector&lt;<span class="type">int</span>&gt; v4 = &#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>&#125;;</span><br><span class="line">    <span class="function">vector&lt;<span class="type">int</span>&gt; <span class="title">v5</span><span class="params">(v4)</span></span>;</span><br><span class="line">    <span class="function">vector&lt;<span class="type">int</span>&gt; <span class="title">v6</span><span class="params">(v<span class="number">4.</span>begin(), v<span class="number">4.</span>begin() + <span class="number">3</span>)</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 1.2 添加元素</span></span><br><span class="line">    v<span class="number">1.</span><span class="built_in">push_back</span>(<span class="number">10</span>);</span><br><span class="line">    v<span class="number">1.</span><span class="built_in">emplace_back</span>(<span class="number">20</span>);</span><br><span class="line">    v<span class="number">1.</span><span class="built_in">insert</span>(v<span class="number">1.</span><span class="built_in">begin</span>(), <span class="number">5</span>);</span><br><span class="line">    v<span class="number">1.</span><span class="built_in">insert</span>(v<span class="number">1.</span><span class="built_in">begin</span>() + <span class="number">2</span>, <span class="number">15</span>);</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 1.3 访问元素</span></span><br><span class="line">    <span class="type">int</span> a = v1[<span class="number">0</span>];</span><br><span class="line">    <span class="type">int</span> b = v<span class="number">1.</span><span class="built_in">at</span>(<span class="number">1</span>);</span><br><span class="line">    <span class="type">int</span> c = v<span class="number">1.f</span>ront();</span><br><span class="line">    <span class="type">int</span> d = v<span class="number">1.</span><span class="built_in">back</span>();</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 1.4 删除元素</span></span><br><span class="line">    v<span class="number">1.</span><span class="built_in">pop_back</span>();</span><br><span class="line">    v<span class="number">1.</span><span class="built_in">erase</span>(v<span class="number">1.</span><span class="built_in">begin</span>() + <span class="number">1</span>);</span><br><span class="line">    v<span class="number">1.</span><span class="built_in">erase</span>(v<span class="number">1.</span><span class="built_in">begin</span>(), v<span class="number">1.</span><span class="built_in">begin</span>() + <span class="number">2</span>);</span><br><span class="line">    v<span class="number">1.</span><span class="built_in">clear</span>();</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 1.5 大小和容量</span></span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;大小: &quot;</span> &lt;&lt; v<span class="number">1.</span><span class="built_in">size</span>() &lt;&lt; endl;</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;容量: &quot;</span> &lt;&lt; v<span class="number">1.</span><span class="built_in">capacity</span>() &lt;&lt; endl;</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;是否为空: &quot;</span> &lt;&lt; v<span class="number">1.</span><span class="built_in">empty</span>() &lt;&lt; endl;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 1.6 调整大小</span></span><br><span class="line">    v<span class="number">1.</span><span class="built_in">resize</span>(<span class="number">20</span>);</span><br><span class="line">    v<span class="number">1.</span><span class="built_in">resize</span>(<span class="number">25</span>, <span class="number">100</span>);</span><br><span class="line">    v<span class="number">1.</span><span class="built_in">reserve</span>(<span class="number">100</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// ==================== 2. vector 遍历 ====================</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">vector_traversal</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    vector&lt;<span class="type">int</span>&gt; v = &#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>&#125;;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; v.<span class="built_in">size</span>(); i++) &#123;</span><br><span class="line">        cout &lt;&lt; v[i] &lt;&lt; <span class="string">&quot; &quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">auto</span> it = v.<span class="built_in">begin</span>(); it != v.<span class="built_in">end</span>(); ++it) &#123;</span><br><span class="line">        cout &lt;&lt; *it &lt;&lt; <span class="string">&quot; &quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">auto</span> it = v.<span class="built_in">rbegin</span>(); it != v.<span class="built_in">rend</span>(); ++it) &#123;</span><br><span class="line">        cout &lt;&lt; *it &lt;&lt; <span class="string">&quot; &quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> x : v) &#123;</span><br><span class="line">        cout &lt;&lt; x &lt;&lt; <span class="string">&quot; &quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span>&amp; x : v) &#123;</span><br><span class="line">        x *= <span class="number">2</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// ==================== 3. vector 常用算法 ====================</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">vector_algorithms</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    vector&lt;<span class="type">int</span>&gt; v = &#123;<span class="number">5</span>, <span class="number">2</span>, <span class="number">8</span>, <span class="number">1</span>, <span class="number">9</span>, <span class="number">3</span>, <span class="number">7</span>, <span class="number">4</span>, <span class="number">6</span>&#125;;</span><br><span class="line">    </span><br><span class="line">    <span class="built_in">sort</span>(v.<span class="built_in">begin</span>(), v.<span class="built_in">end</span>());</span><br><span class="line">    <span class="built_in">sort</span>(v.<span class="built_in">begin</span>(), v.<span class="built_in">end</span>(), <span class="built_in">greater</span>&lt;<span class="type">int</span>&gt;());</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">auto</span> it = <span class="built_in">find</span>(v.<span class="built_in">begin</span>(), v.<span class="built_in">end</span>(), <span class="number">5</span>);</span><br><span class="line">    <span class="keyword">if</span> (it != v.<span class="built_in">end</span>()) &#123;</span><br><span class="line">        cout &lt;&lt; <span class="string">&quot;找到了: &quot;</span> &lt;&lt; *it &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">if</span> (<span class="built_in">binary_search</span>(v.<span class="built_in">begin</span>(), v.<span class="built_in">end</span>(), <span class="number">5</span>)) &#123;</span><br><span class="line">        cout &lt;&lt; <span class="string">&quot;存在&quot;</span> &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="built_in">reverse</span>(v.<span class="built_in">begin</span>(), v.<span class="built_in">end</span>());</span><br><span class="line">    </span><br><span class="line">    <span class="built_in">sort</span>(v.<span class="built_in">begin</span>(), v.<span class="built_in">end</span>());</span><br><span class="line">    <span class="keyword">auto</span> last = <span class="built_in">unique</span>(v.<span class="built_in">begin</span>(), v.<span class="built_in">end</span>());</span><br><span class="line">    v.<span class="built_in">erase</span>(last, v.<span class="built_in">end</span>());</span><br><span class="line">    </span><br><span class="line">    <span class="type">int</span> maxVal = *<span class="built_in">max_element</span>(v.<span class="built_in">begin</span>(), v.<span class="built_in">end</span>());</span><br><span class="line">    <span class="type">int</span> minVal = *<span class="built_in">min_element</span>(v.<span class="built_in">begin</span>(), v.<span class="built_in">end</span>());</span><br><span class="line">    </span><br><span class="line">    <span class="type">int</span> sum = <span class="built_in">accumulate</span>(v.<span class="built_in">begin</span>(), v.<span class="built_in">end</span>(), <span class="number">0</span>);</span><br><span class="line">    </span><br><span class="line">    <span class="type">int</span> cnt = <span class="built_in">count</span>(v.<span class="built_in">begin</span>(), v.<span class="built_in">end</span>(), <span class="number">5</span>);</span><br><span class="line">    </span><br><span class="line">    <span class="built_in">fill</span>(v.<span class="built_in">begin</span>(), v.<span class="built_in">begin</span>() + <span class="number">5</span>, <span class="number">100</span>);</span><br><span class="line">    </span><br><span class="line">    <span class="built_in">random_shuffle</span>(v.<span class="built_in">begin</span>(), v.<span class="built_in">end</span>());</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// ==================== 4. 二维vector ====================</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">vector_2d</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    vector&lt;vector&lt;<span class="type">int</span>&gt;&gt; matrix1;</span><br><span class="line">    </span><br><span class="line">    vector&lt;vector&lt;<span class="type">int</span>&gt;&gt; <span class="built_in">matrix2</span>(<span class="number">3</span>, <span class="built_in">vector</span>&lt;<span class="type">int</span>&gt;(<span class="number">4</span>, <span class="number">0</span>));</span><br><span class="line">    </span><br><span class="line">    vector&lt;vector&lt;<span class="type">int</span>&gt;&gt; matrix3 = &#123;</span><br><span class="line">        &#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>&#125;,</span><br><span class="line">        &#123;<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>&#125;,</span><br><span class="line">        &#123;<span class="number">7</span>, <span class="number">8</span>, <span class="number">9</span>&#125;</span><br><span class="line">    &#125;;</span><br><span class="line">    </span><br><span class="line">    vector&lt;vector&lt;<span class="type">int</span>&gt;&gt; matrix4;</span><br><span class="line">    matrix<span class="number">4.</span><span class="built_in">push_back</span>(&#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>&#125;);</span><br><span class="line">    matrix<span class="number">4.</span><span class="built_in">push_back</span>(<span class="built_in">vector</span>&lt;<span class="type">int</span>&gt;(<span class="number">4</span>, <span class="number">0</span>));</span><br><span class="line">    </span><br><span class="line">    <span class="type">int</span> val = matrix3[<span class="number">1</span>][<span class="number">2</span>];</span><br><span class="line">    matrix3[<span class="number">0</span>][<span class="number">1</span>] = <span class="number">10</span>;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; matrix<span class="number">3.</span><span class="built_in">size</span>(); i++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">0</span>; j &lt; matrix3[i].<span class="built_in">size</span>(); j++) &#123;</span><br><span class="line">            cout &lt;&lt; matrix3[i][j] &lt;&lt; <span class="string">&quot; &quot;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        cout &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span> (<span class="type">const</span> <span class="keyword">auto</span>&amp; row : matrix3) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> x : row) &#123;</span><br><span class="line">            cout &lt;&lt; x &lt;&lt; <span class="string">&quot; &quot;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        cout &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// ==================== 5. vector实现邻接表 ====================</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Graph</span> &#123;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="type">int</span> n;</span><br><span class="line">    vector&lt;vector&lt;<span class="type">int</span>&gt;&gt; adj;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">dfsHelper</span><span class="params">(<span class="type">int</span> u, vector&lt;<span class="type">bool</span>&gt;&amp; visited)</span> </span>&#123;</span><br><span class="line">        visited[u] = <span class="literal">true</span>;</span><br><span class="line">        cout &lt;&lt; u &lt;&lt; <span class="string">&quot; &quot;</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> v : adj[u]) &#123;</span><br><span class="line">            <span class="keyword">if</span> (!visited[v]) &#123;</span><br><span class="line">                <span class="built_in">dfsHelper</span>(v, visited);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">Graph</span>(<span class="type">int</span> vertices) : <span class="built_in">n</span>(vertices), <span class="built_in">adj</span>(vertices + <span class="number">1</span>) &#123;&#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">addEdge</span><span class="params">(<span class="type">int</span> u, <span class="type">int</span> v)</span> </span>&#123;</span><br><span class="line">        adj[u].<span class="built_in">push_back</span>(v);</span><br><span class="line">        adj[v].<span class="built_in">push_back</span>(u);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">addDirectedEdge</span><span class="params">(<span class="type">int</span> u, <span class="type">int</span> v)</span> </span>&#123;</span><br><span class="line">        adj[u].<span class="built_in">push_back</span>(v);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">removeEdge</span><span class="params">(<span class="type">int</span> u, <span class="type">int</span> v)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">auto</span>&amp; neighbors = adj[u];</span><br><span class="line">        neighbors.<span class="built_in">erase</span>(<span class="built_in">remove</span>(neighbors.<span class="built_in">begin</span>(), neighbors.<span class="built_in">end</span>(), v), neighbors.<span class="built_in">end</span>());</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="type">bool</span> <span class="title">hasEdge</span><span class="params">(<span class="type">int</span> u, <span class="type">int</span> v)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> neighbor : adj[u]) &#123;</span><br><span class="line">            <span class="keyword">if</span> (neighbor == v) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function">vector&lt;<span class="type">int</span>&gt; <span class="title">getNeighbors</span><span class="params">(<span class="type">int</span> u)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> adj[u];</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">print</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">            cout &lt;&lt; i &lt;&lt; <span class="string">&quot;: &quot;</span>;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> neighbor : adj[i]) &#123;</span><br><span class="line">                cout &lt;&lt; neighbor &lt;&lt; <span class="string">&quot; &quot;</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            cout &lt;&lt; endl;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> start)</span> </span>&#123;</span><br><span class="line">        <span class="function">vector&lt;<span class="type">bool</span>&gt; <span class="title">visited</span><span class="params">(n + <span class="number">1</span>, <span class="literal">false</span>)</span></span>;</span><br><span class="line">        <span class="built_in">dfsHelper</span>(start, visited);</span><br><span class="line">        cout &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">bfs</span><span class="params">(<span class="type">int</span> start)</span> </span>&#123;</span><br><span class="line">        <span class="function">vector&lt;<span class="type">bool</span>&gt; <span class="title">visited</span><span class="params">(n + <span class="number">1</span>, <span class="literal">false</span>)</span></span>;</span><br><span class="line">        queue&lt;<span class="type">int</span>&gt; q;</span><br><span class="line">        </span><br><span class="line">        visited[start] = <span class="literal">true</span>;</span><br><span class="line">        q.<span class="built_in">push</span>(start);</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">while</span> (!q.<span class="built_in">empty</span>()) &#123;</span><br><span class="line">            <span class="type">int</span> u = q.<span class="built_in">front</span>();</span><br><span class="line">            q.<span class="built_in">pop</span>();</span><br><span class="line">            cout &lt;&lt; u &lt;&lt; <span class="string">&quot; &quot;</span>;</span><br><span class="line">            </span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> v : adj[u]) &#123;</span><br><span class="line">                <span class="keyword">if</span> (!visited[v]) &#123;</span><br><span class="line">                    visited[v] = <span class="literal">true</span>;</span><br><span class="line">                    q.<span class="built_in">push</span>(v);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        cout &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="type">int</span> <span class="title">countComponents</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="function">vector&lt;<span class="type">bool</span>&gt; <span class="title">visited</span><span class="params">(n + <span class="number">1</span>, <span class="literal">false</span>)</span></span>;</span><br><span class="line">        <span class="type">int</span> count = <span class="number">0</span>;</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (!visited[i]) &#123;</span><br><span class="line">                count++;</span><br><span class="line">                <span class="built_in">dfsHelper</span>(i, visited);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> count;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">Edge</span> &#123;</span><br><span class="line">    <span class="type">int</span> to;</span><br><span class="line">    <span class="type">int</span> weight;</span><br><span class="line">    <span class="built_in">Edge</span>(<span class="type">int</span> t, <span class="type">int</span> w) : <span class="built_in">to</span>(t), <span class="built_in">weight</span>(w) &#123;&#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">WeightedGraph</span> &#123;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="type">int</span> n;</span><br><span class="line">    vector&lt;vector&lt;Edge&gt;&gt; adj;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">WeightedGraph</span>(<span class="type">int</span> vertices) : <span class="built_in">n</span>(vertices), <span class="built_in">adj</span>(vertices + <span class="number">1</span>) &#123;&#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">addEdge</span><span class="params">(<span class="type">int</span> u, <span class="type">int</span> v, <span class="type">int</span> w)</span> </span>&#123;</span><br><span class="line">        adj[u].<span class="built_in">emplace_back</span>(v, w);</span><br><span class="line">        adj[v].<span class="built_in">emplace_back</span>(u, w);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">print</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">            cout &lt;&lt; i &lt;&lt; <span class="string">&quot;: &quot;</span>;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">const</span> Edge&amp; e : adj[i]) &#123;</span><br><span class="line">                cout &lt;&lt; <span class="string">&quot;(&quot;</span> &lt;&lt; e.to &lt;&lt; <span class="string">&quot;,&quot;</span> &lt;&lt; e.weight &lt;&lt; <span class="string">&quot;) &quot;</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            cout &lt;&lt; endl;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="number">3</span>`</span><br></pre></td></tr></table></div></figure>]]></content>
      
      
      <categories>
          
          <category> 算法 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 算法 </tag>
            
            <tag> acm </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>cpp</title>
      <link href="/2026/01/26/cpp/"/>
      <url>/2026/01/26/cpp/</url>
      
        <content type="html"><![CDATA[        <h1 id="实现一个基于TCP的最小服务器程序"   >          <a href="#实现一个基于TCP的最小服务器程序" class="heading-link"><i class="fas fa-link"></i></a><a href="#实现一个基于TCP的最小服务器程序" class="headerlink" title="实现一个基于TCP的最小服务器程序"></a>实现一个基于TCP的最小服务器程序</h1>      <ul><li>在本机8080端口启动一个tcp服务器</li><li>等待客户端连接</li><li>接受一个客户端后向其发送一条字符串消息，然后关闭连接并退出程序</li></ul><p>为了实现这套流程，我们需要以下步骤</p><ol><li>创建socket，申请网络通信资源（这里的是监听socket_fd）</li><li>准备服务器地质结构（IP＋端口）</li><li>bind绑定socket和地址（占用端口）</li><li>进入监听状态等待客户端，为这个客户端创建一个专属socket</li><li>向客户端发送数据</li></ol><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;cstring&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;unistd.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;arpa/inet.h&gt;</span>   </span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;sys/socket.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="comment">//server_fd不是socket对象，是socket的文件描述符</span></span><br><span class="line">    <span class="type">int</span> server_fd=<span class="built_in">socket</span>(AF_INET,SOCK_STREAM,<span class="number">0</span>);<span class="comment">//AF_INET表示IPV4，SOCK_STREAM表示TCP协议</span></span><br><span class="line">    <span class="keyword">if</span>(server_fd==<span class="number">-1</span>)&#123;</span><br><span class="line">        cerr&lt;&lt;<span class="string">&quot;Socket create failed&quot;</span>&lt;&lt;endl;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span>;      </span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//以下三行告诉你。我要创建一个IPV4服务器，监听本机所有ip，端口号是8080</span></span><br><span class="line">    sockaddr_in address;<span class="comment">//sockaddr_in是IPV4专用地址结构体</span></span><br><span class="line">    address.sin_family=AF_INET;<span class="comment">//告诉系统这是一个IPV4地址</span></span><br><span class="line">    address.sin_addr.s_addr=INADDR_ANY;<span class="comment">//sin_addr是一个结构体，s_addr里面存真正的ip字段、</span></span><br><span class="line">    <span class="comment">//INADDR_ANY表示监听本机所有网卡的ip地址，机器可能有127.0，0.1本地回环，192.168.1.100局域网，公网ip。</span></span><br><span class="line">    <span class="comment">//这个表示不管从哪个ip连接过来，只要端口对就接</span></span><br><span class="line">    <span class="comment">//也可以指定ip写，比如inet_addr(&quot;127.0.0.1&quot;)</span></span><br><span class="line">    address.sin_port=<span class="built_in">htons</span>(<span class="number">8080</span>);</span><br><span class="line">    <span class="comment">//计算机存整数时有两种方式,小端序如x86，大端序如网络传输,网络规定统一使用大端序</span></span><br><span class="line">    <span class="comment">//htons把主机字节序转到网络字节序，htons=Host TO Network Short</span></span><br><span class="line">    <span class="comment">//端口 htons ,ip htonl</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span>(<span class="built_in">bind</span>(server_fd,(<span class="keyword">struct</span> sockaddr*)&amp;address,<span class="built_in">sizeof</span>(address))&lt;<span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//bind作用是把一个socket和一个ip地址和端口号绑定在一起，如果不Bind，服务器是没有地址的</span></span><br><span class="line">    <span class="comment">//这里的socket_fd是之前socket得到的文件描述符，告诉系统是哪个手机要绑定</span></span><br><span class="line">    <span class="comment">//需要把IPV4地址当成通用地址用，是c时代遗留下来的</span></span><br><span class="line">    <span class="comment">//小于0表示失败，可能端口已经被占用或者权限不够或者地址非法</span></span><br><span class="line">    <span class="keyword">if</span>(<span class="built_in">listen</span>(server_fd,<span class="number">3</span>)&lt;<span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//把普通socket变成监听socket，没有listen()，服务器不能连接</span></span><br><span class="line">    <span class="comment">//3表示监听队列的长度，最多允许多少个客户端</span></span><br><span class="line">    cout&lt;&lt;<span class="string">&quot;Listening on port 8080...(Press Ctrl+C to stop)&quot;</span>&lt;&lt;endl;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//等待一个客户端连接，并为这个客户创建一个专属通信socket</span></span><br><span class="line">    <span class="type">int</span> new_socket;<span class="comment">//这是一个通信socket,专门用来服务一个客户端，可以用来send,recv,close</span></span><br><span class="line">    <span class="type">int</span> addrlen=<span class="built_in">sizeof</span>(address);</span><br><span class="line">    new_socket=<span class="built_in">accept</span>(server_fd,(<span class="keyword">struct</span> sockaddr*)&amp;address,(<span class="type">socklen_t</span>*)&amp;addrlen);</span><br><span class="line">    <span class="comment">//第一个参数表示从哪个监听socket上接人，第二个参数是一个输出参数，会把客户端的ip和端口写进去，第三个参数是告诉系统address有多大，输出实际写了多少字节</span></span><br><span class="line">    <span class="keyword">if</span>(new_socket&lt;<span class="number">0</span>)&#123;</span><br><span class="line">        cerr&lt;&lt;<span class="string">&quot;Accept failed&quot;</span>&lt;&lt;endl;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    cout&lt;&lt;<span class="string">&quot;Connection accepted&quot;</span>&lt;&lt;endl;</span><br><span class="line"></span><br><span class="line">    <span class="type">const</span> <span class="type">char</span>* hello=<span class="string">&quot;Hello from server&quot;</span>;<span class="comment">//我准备要发送的数据</span></span><br><span class="line">    <span class="built_in">send</span>(new_socket,hello,<span class="built_in">strlen</span>(hello),<span class="number">0</span>);</span><br><span class="line">    <span class="comment">//第一个参数表示和哪个客户端通信，第二个参数是发送的数据地址，第三个是发送多少字节，第四个是默认行为</span></span><br><span class="line">    <span class="comment">//send并不保证一次把所有数据都发完，返回值小于len是可能的</span></span><br><span class="line">    cout&lt;&lt;<span class="string">&quot;Response sent.&quot;</span>&lt;&lt;endl;</span><br><span class="line"></span><br><span class="line">    <span class="built_in">close</span>(new_socket);<span class="comment">//关闭和这个客户端的tcp连接。此时客户端再recv()会受到0.tcp会进行四次挥手，但是服务器仍然存在</span></span><br><span class="line">    <span class="built_in">close</span>(server_fd);<span class="comment">//服务器彻底下线</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>该代码展示了 TCP 服务器从创建、监听、接受连接到通信和关闭的完整流程，是理解 C++ 网络编程和操作系统网络接口的最小可运行示例。</p>        <h1 id="多线程并发服务器"   >          <a href="#多线程并发服务器" class="heading-link"><i class="fas fa-link"></i></a><a href="#多线程并发服务器" class="headerlink" title="多线程并发服务器"></a>多线程并发服务器</h1>      <p>在刚刚的代码中我们可以发现一个显著问题，</p>]]></content>
      
      
      <categories>
          
          <category> 算法 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> cpp </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>贪心</title>
      <link href="/2025/11/26/%E8%B4%AA%E5%BF%83/"/>
      <url>/2025/11/26/%E8%B4%AA%E5%BF%83/</url>
      
        <content type="html"><![CDATA[        <h1 id="概念简介"   >          <a href="#概念简介" class="heading-link"><i class="fas fa-link"></i></a><a href="#概念简介" class="headerlink" title="概念简介"></a>概念简介</h1>              <h2 id="贪心原理"   >          <a href="#贪心原理" class="heading-link"><i class="fas fa-link"></i></a><a href="#贪心原理" class="headerlink" title="贪心原理"></a>贪心原理</h2>      <p>贪心算法的核心就是一个字：贪。总是<strong>做出当前看来最优的选择</strong>，因此可知，贪心算法不从整体去考虑，<strong>它做出的选择也是局部最优选择</strong>，<strong>从而达到全局优化选择</strong>。我们只关注目前的利益，从而达到利益最大化，尽管贪心算法不一定能得到最优解，面对相当数量的一部分问题，我们是可以得到正确的答案的。</p><p>从问题的某一个初始解，一步步推论，保证每一步都是最为优化的，出发逐步逼近给定的目标，以尽可能快的地求得更好的解。</p><p>当接下来的任意一步都无法达到最优时，贪心算法结束。</p>        <h2 id="贪心算法的弊病"   >          <a href="#贪心算法的弊病" class="heading-link"><i class="fas fa-link"></i></a><a href="#贪心算法的弊病" class="headerlink" title="贪心算法的弊病"></a>贪心算法的弊病</h2>      <ol><li><strong>不能保证求得的最后解是最佳的；</strong></li><li>不能用来求最大或最小解问题；</li><li>只能求满足某些约束条件的可行解的范围。</li></ol>        <h1 id="部分背包问题"   >          <a href="#部分背包问题" class="heading-link"><i class="fas fa-link"></i></a><a href="#部分背包问题" class="headerlink" title="部分背包问题"></a>部分背包问题</h1>      <p><span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/P2240" >P2240 【深基12.例1】部分背包问题 - 洛谷</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>        <h2 id="题意"   >          <a href="#题意" class="heading-link"><i class="fas fa-link"></i></a><a href="#题意" class="headerlink" title="题意"></a>题意</h2>      <ul><li>有 N 堆金币，每堆金币有总重量 <em>mi</em>和总价值 <em>vi</em>。</li><li>背包最大承重为 T。</li><li>金币可以按任意比例分割，分割后单位价值（价值&#x2F;重量）不变。</li><li>目标：在不超过背包容量的情况下，拿走<strong>最大总价值</strong>的金币。</li></ul>        <h2 id="思路"   >          <a href="#思路" class="heading-link"><i class="fas fa-link"></i></a><a href="#思路" class="headerlink" title="思路"></a>思路</h2>      <p>一道简单的不能再简单的入门贪心题目，为了收益最大化，肯定要选择单价最高的金币优先拿。v&#x2F;m即可然后排序即可。要注意的是要用<strong>double</strong>。从贵的往便宜的拿，如果拿得下全拿，拿不下的话，填满剩余背包容量</p>        <h2 id="代码"   >          <a href="#代码" class="heading-link"><i class="fas fa-link"></i></a><a href="#代码" class="headerlink" title="代码"></a>代码</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="meta">#<span class="keyword">define</span> int long long </span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> endl <span class="string">&quot;\n&quot;</span></span></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N=<span class="number">10005</span>,inf=<span class="number">2e18</span>,mod=<span class="number">998244353</span>;</span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">coins</span>&#123;</span><br><span class="line">    <span class="type">double</span> m, v;</span><br><span class="line">    <span class="type">double</span> price;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="function"><span class="type">bool</span> <span class="title">cmp</span><span class="params">(coins a, coins b)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> a.price &gt; b.price;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">solve</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="function">vector&lt;coins&gt; <span class="title">coin</span><span class="params">(N)</span></span>;</span><br><span class="line">    <span class="type">double</span> n, t;</span><br><span class="line">    cin &gt;&gt; n &gt;&gt; t;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++)&#123;</span><br><span class="line">        cin&gt;&gt;coin[i].m&gt;&gt;coin[i].v;</span><br><span class="line">        coin[i].price = coin[i].v / coin[i].m;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">sort</span>(coin.<span class="built_in">begin</span>()<span class="number">+1</span>, coin.<span class="built_in">begin</span>()+n<span class="number">+1</span>, cmp);</span><br><span class="line">    <span class="type">double</span> sum_m= <span class="number">0</span>, sum_v = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++)&#123;</span><br><span class="line">        <span class="keyword">if</span>(sum_m+coin[i].m &lt;= t)&#123;</span><br><span class="line">            sum_m += coin[i].m;</span><br><span class="line">            sum_v += coin[i].v;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="type">double</span> cha=t-sum_m;</span><br><span class="line">            sum_v += cha*(coin[i].v/coin[i].m);</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    cout &lt;&lt; fixed &lt;&lt; <span class="built_in">setprecision</span>(<span class="number">2</span>) &lt;&lt; sum_v &lt;&lt; endl;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">signed</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    ios::<span class="built_in">sync_with_stdio</span>(<span class="number">0</span>),cin.<span class="built_in">tie</span>(<span class="number">0</span>),cout.<span class="built_in">tie</span>(<span class="number">0</span>);</span><br><span class="line">    <span class="type">int</span> t=<span class="number">1</span>;</span><br><span class="line">    <span class="comment">//cin&gt;&gt;t;</span></span><br><span class="line">    <span class="keyword">while</span>(t--)&#123;</span><br><span class="line">        <span class="built_in">solve</span>();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="均分纸牌"   >          <a href="#均分纸牌" class="heading-link"><i class="fas fa-link"></i></a><a href="#均分纸牌" class="headerlink" title="均分纸牌"></a>均分纸牌</h1>      <p>[P1031 <span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/P1031" >NOIP 2002 提高组] 均分纸牌 - 洛谷</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>        <h2 id="题意-1"   >          <a href="#题意-1" class="heading-link"><i class="fas fa-link"></i></a><a href="#题意-1" class="headerlink" title="题意"></a>题意</h2>      <ul><li>有 N 堆纸牌，每堆有若干张，纸牌总数是 N 的倍数（保证可以均分）。</li><li>移动规则：第 1 堆：只能向右移动（移到第 2 堆）第 N 堆：只能向左移动（移到第 N-1 堆）其他堆：可以向左右两边移动</li><li>一次移动：从一堆取若干张牌移到相邻堆</li><li>目标：让每堆牌数相同，求<strong>最少移动次数</strong></li></ul>        <h2 id="思路-1"   >          <a href="#思路-1" class="heading-link"><i class="fas fa-link"></i></a><a href="#思路-1" class="headerlink" title="思路"></a>思路</h2>      <p>这其实是一个<strong>线性传输问题</strong>，在运筹学中可以证明，单向调整（从左到右）得到的流量方案 <em>xi</em>是使得非零流量次数最少的方法。</p><p>不说严谨的证明了，自己脑补一下。</p><p><strong>贪心思路如下：</strong></p><ol><li>计算平均值 <code>avg = 总牌数 / N</code></li><li>从左到右遍历：如果当前堆牌数 ≠ avg，则计算差值，需要从当前堆向下一堆移动（正数表示多出的要移走，负数表示缺少的要拿来）只要差值不为 0，就计为一次移动</li></ol><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="meta">#<span class="keyword">define</span> int long long </span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> endl <span class="string">&quot;\n&quot;</span></span></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N=<span class="number">2e5</span><span class="number">+7</span>,inf=<span class="number">2e18</span>,mod=<span class="number">998244353</span>;</span><br><span class="line"><span class="type">int</span> a[N];</span><br><span class="line"><span class="type">int</span> sum = <span class="number">0</span>,max1=<span class="number">0</span>,pos=<span class="number">0</span>;</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">solve</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="type">int</span> n;</span><br><span class="line">    cin&gt;&gt;n;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">1</span>;i&lt;=n;i++)&#123;</span><br><span class="line">        cin&gt;&gt;a[i];</span><br><span class="line">        sum+=a[i];</span><br><span class="line">        <span class="keyword">if</span>(a[i]&gt;max1)&#123;</span><br><span class="line">            max1=a[i];</span><br><span class="line">            pos=i;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="type">int</span> aver=sum/n;</span><br><span class="line">    <span class="type">int</span> cnt = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n;i++)&#123;</span><br><span class="line">        <span class="keyword">if</span>(a[i]==aver)&#123;</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        a[i + <span class="number">1</span>] += (a[i] - aver);</span><br><span class="line">        a[i] = aver;</span><br><span class="line">        cnt++;</span><br><span class="line">&#125;</span><br><span class="line">    cout&lt;&lt;cnt&lt;&lt;endl;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">signed</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    ios::<span class="built_in">sync_with_stdio</span>(<span class="number">0</span>),cin.<span class="built_in">tie</span>(<span class="number">0</span>),cout.<span class="built_in">tie</span>(<span class="number">0</span>);</span><br><span class="line">    <span class="type">int</span> t=<span class="number">1</span>;</span><br><span class="line">    <span class="comment">//cin&gt;&gt;t;</span></span><br><span class="line">    <span class="keyword">while</span>(t--)&#123;</span><br><span class="line">        <span class="built_in">solve</span>();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="守序者的尊严"   >          <a href="#守序者的尊严" class="heading-link"><i class="fas fa-link"></i></a><a href="#守序者的尊严" class="headerlink" title="守序者的尊严"></a>守序者的尊严</h1>      <p><span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/P5639" >P5639 【CSGRound2】守序者的尊严 - 洛谷</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>        <h2 id="题意-2"   >          <a href="#题意-2" class="heading-link"><i class="fas fa-link"></i></a><a href="#题意-2" class="headerlink" title="题意"></a>题意</h2>      <ul><li>一条直线上有 n 个监控，小 Z 要从第 1 个监控位置走到第 n 个监控之后（外卖点）。</li><li>监控开关规律：第 0 秒为初始状态，之后<strong>每秒交替</strong>（开 1 秒 → 关 1 秒 → 开 1 秒 …）。</li><li>小 Z 移动规则：在监控关闭的秒数内，可以一次行动通过<strong>任意多个连续关闭的监控</strong>，耗时 1 秒。如果监控开启，则不能通过（必须等待它关闭）。</li><li>保证第 1 个监控在第 0 秒是关闭的（起步没问题）。</li><li>目标：求<strong>最少需要的总时间（秒数）</strong>。</li></ul>        <h2 id="思路-2"   >          <a href="#思路-2" class="heading-link"><i class="fas fa-link"></i></a><a href="#思路-2" class="headerlink" title="思路"></a>思路</h2>      <p>可以无脑暴力模拟锻炼一下码力，然后喜提70分</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">while</span>(<span class="number">1</span>)&#123;</span><br><span class="line">       <span class="keyword">for</span> (<span class="type">int</span> i = pos; i &lt;= n;i++)&#123;</span><br><span class="line">           <span class="keyword">if</span>(a[i]==<span class="number">0</span>)&#123;</span><br><span class="line">               pos = i;</span><br><span class="line">           &#125;</span><br><span class="line">           <span class="keyword">else</span>&#123;</span><br><span class="line">               cnt++;</span><br><span class="line">               <span class="keyword">break</span>;</span><br><span class="line">           &#125;</span><br><span class="line">       &#125;</span><br><span class="line">       <span class="keyword">for</span>(<span class="type">int</span> i=pos<span class="number">+1</span>;i&lt;=n;i++)&#123;</span><br><span class="line">           a[i]=<span class="number">1</span>-a[i];</span><br><span class="line">       &#125;</span><br><span class="line">       <span class="keyword">if</span>(pos==n)&#123;</span><br><span class="line">           <span class="keyword">break</span>;</span><br><span class="line">       &#125;</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></div></figure><p>显然是不能暴力的，但是其实也不需要暴力，因为每一次其实小Z都会疾速移动到10交界处，你算一下有几个交界处就好。最后的答案是交界处个数加一。注意，如果开头是1，那么第一秒是不可以动的，要原地等一秒。</p>        <h2 id="代码-1"   >          <a href="#代码-1" class="heading-link"><i class="fas fa-link"></i></a><a href="#代码-1" class="headerlink" title="代码"></a>代码</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="meta">#<span class="keyword">define</span> int long long </span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> endl <span class="string">&quot;\n&quot;</span></span></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N=<span class="number">1000005</span>,inf=<span class="number">2e18</span>,mod=<span class="number">998244353</span>;</span><br><span class="line"><span class="type">int</span> a[N];</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">solve</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="type">int</span> n;</span><br><span class="line">    cin&gt;&gt;n;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">1</span>;i&lt;=n;i++)&#123;</span><br><span class="line">        cin&gt;&gt;a[i];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="type">int</span> cnt = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt; n; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span>(a[i]!=a[i<span class="number">+1</span>])&#123;</span><br><span class="line">            cnt++;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(a[<span class="number">1</span>]==<span class="number">1</span>)&#123;</span><br><span class="line">        cnt++;</span><br><span class="line">    &#125;</span><br><span class="line">    cout&lt;&lt;(cnt<span class="number">+1</span>)&lt;&lt;endl;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">signed</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    ios::<span class="built_in">sync_with_stdio</span>(<span class="number">0</span>),cin.<span class="built_in">tie</span>(<span class="number">0</span>),cout.<span class="built_in">tie</span>(<span class="number">0</span>);</span><br><span class="line">    <span class="type">int</span> t=<span class="number">1</span>;</span><br><span class="line">    <span class="comment">//cin&gt;&gt;t;</span></span><br><span class="line">    <span class="keyword">while</span>(t--)&#123;</span><br><span class="line">        <span class="built_in">solve</span>();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="骑士的工作"   >          <a href="#骑士的工作" class="heading-link"><i class="fas fa-link"></i></a><a href="#骑士的工作" class="headerlink" title="骑士的工作"></a>骑士的工作</h1>      <p><span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/P2695" >P2695 骑士的工作 - 洛谷</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>        <h2 id="题意-3"   >          <a href="#题意-3" class="heading-link"><i class="fas fa-link"></i></a><a href="#题意-3" class="headerlink" title="题意"></a>题意</h2>      <p>村庄里来了一只恶龙，他有 <em>n</em> 个头，每个头大小不同。恶龙到处杀人放火。骑士团里面有 <em>m</em> 位成员</p><p>每个人都可以砍掉<strong>至多</strong>一个大小不超过 <em>zi</em> 的头，需要 <em>zi</em> 个金币，求最小花费。</p>        <h2 id="思路-3"   >          <a href="#思路-3" class="heading-link"><i class="fas fa-link"></i></a><a href="#思路-3" class="headerlink" title="思路"></a>思路</h2>      <p>有道是杀鸡焉用牛刀，所以我们肯定不能用很厉害的骑士去砍瓜切菜。而是用最菜的但是能赢的骑士去砍头。</p><p>也就是说，用能力值<strong>刚好大于等于</strong>头的大小的最便宜骑士去砍。只需要递增排列逐个遍历，从最弱到最强，看能不能砍下来。能砍下来就标记一下当前骑士已经出战过了（ 出战过的不能再战），然后把金币加到sum里面，break掉，到下一个头。当然砍过的头我们令其为0，如果最后有头不是0就说明头每砍完。</p>        <h2 id="代码-2"   >          <a href="#代码-2" class="heading-link"><i class="fas fa-link"></i></a><a href="#代码-2" class="headerlink" title="代码"></a>代码</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="meta">#<span class="keyword">define</span> int long long </span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> endl <span class="string">&quot;\n&quot;</span></span></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N=<span class="number">100005</span>,inf=<span class="number">2e18</span>,mod=<span class="number">998244353</span>;</span><br><span class="line"><span class="type">int</span> head[N], kill1[N];</span><br><span class="line"><span class="type">bool</span> vis[N];</span><br><span class="line"><span class="type">bool</span> flag = <span class="literal">true</span>;</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">solve</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="type">int</span> n, m;</span><br><span class="line">    cin &gt;&gt; n &gt;&gt; m;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++)&#123;</span><br><span class="line">        cin &gt;&gt;head[i];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i &lt;= m; i++)&#123;</span><br><span class="line">        cin &gt;&gt; kill1[i];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">sort</span>(kill1 + <span class="number">1</span>, kill1 + m + <span class="number">1</span>);</span><br><span class="line">    <span class="built_in">sort</span>(head + <span class="number">1</span>, head + n + <span class="number">1</span>);</span><br><span class="line">    <span class="type">int</span> sum = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++)&#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> j = <span class="number">1</span>; j &lt;= m; j++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(!vis[j])&#123;</span><br><span class="line">            <span class="keyword">if</span>(head[i]&lt;=kill1[j])&#123;</span><br><span class="line">                sum+=kill1[j];</span><br><span class="line">                head[i] = <span class="number">0</span>;</span><br><span class="line">                vis[j] = <span class="literal">true</span>;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++)&#123;</span><br><span class="line">       <span class="keyword">if</span>(head[i]!=<span class="number">0</span>)&#123;</span><br><span class="line">           flag = <span class="literal">false</span>;</span><br><span class="line">       &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(flag)&#123;</span><br><span class="line">        cout &lt;&lt; sum &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span>&#123;</span><br><span class="line">        cout &lt;&lt; <span class="string">&quot;you died!&quot;</span>&lt;&lt;endl;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">signed</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    ios::<span class="built_in">sync_with_stdio</span>(<span class="number">0</span>),cin.<span class="built_in">tie</span>(<span class="number">0</span>),cout.<span class="built_in">tie</span>(<span class="number">0</span>);</span><br><span class="line">    <span class="type">int</span> t=<span class="number">1</span>;</span><br><span class="line">    <span class="comment">//cin&gt;&gt;t;</span></span><br><span class="line">    <span class="keyword">while</span>(t--)&#123;</span><br><span class="line">        <span class="built_in">solve</span>();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>]]></content>
      
      
      <categories>
          
          <category> 算法 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 算法 </tag>
            
            <tag> acm </tag>
            
            <tag> 贪心 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>明明明月是前身</title>
      <link href="/2025/11/24/%E6%98%8E%E6%98%8E%E6%98%8E%E6%9C%88%E6%98%AF%E5%89%8D%E8%BA%AB/"/>
      <url>/2025/11/24/%E6%98%8E%E6%98%8E%E6%98%8E%E6%9C%88%E6%98%AF%E5%89%8D%E8%BA%AB/</url>
      
        <content type="html"><![CDATA[<p>11</p><blockquote><p>临江仙 明月寺前明月夜</p><p>明月寺前明月夜，依然月色如银。明明明月是前身。回头成一笑，清冷几千春。<br>照彻大千清似水，也曾照彻微尘。莫将圆相换眉颦。人间三五夜，误了镜中人。</p></blockquote><p>赏诗是件雅事，此时心便不可为世俗所扰，否则你的文字也不免沾上俗气。所以离我看到这首诗，到现在提笔写这篇文章，竟已耽搁了四五日。</p><p>不敢说饱读诗书，只是李杜苏辛的雅章倒也拜读过一些。</p><p>概览诗坛，尽显诗人风姿的，李白之狂想，“<strong>应是天仙狂醉，乱把白云揉碎</strong>”，何等逸气浪漫；苏轼之达观，“<strong>且将新火试新茶，诗酒趁年华</strong>”，何等洒脱超然。</p><p>炼字到极致的，亦有宋祁“<strong>红杏枝头春意闹</strong>”，张先“<strong>云破月来花弄影</strong>”。</p><p>声律运用绝佳的，有李清照“<strong>寻寻觅觅，冷冷清清，凄凄惨惨戚戚</strong>”。</p><p>思想境界超脱的，有王维“<strong>行到水穷处，坐看云起时</strong>”，有陶渊明“<strong>采菊东篱下，悠然见南山</strong>”。……</p><p>不自觉又掉了好多书袋，然而只是做个铺垫。</p><p>第一次看到这首词，并非全文，然而只看了一句“明明明月是前身”，便教我大为惊艳震撼，急不可耐的取去查了全诗。我大概不算见识短浅的，不至于<strong>蜀犬吠日</strong>。甚至可以说被诗坛那些天才养刁了眼，所以极少有一眼能让我惊艳的诗词。而更让我震撼的是，这首词竟诞生于晚清。</p><p>常言，唐诗宋词元曲明清小说，在这个满人当权的政府，在这个诗词并不盛行的朝代，在那些千古佳句已经被前人写尽的情况下，竟然还有这种作品。我曾以为纳兰已是诗词在清朝的绝唱，现在想来实在是浅薄了。</p><p>凭此一词，凭此一句，何逊于前朝。</p><p>翻译是不难的，我也不想着墨于此，落了俗气。容许我主观一些了。</p><p>“明明明月是前身”，词中较忌字的重复使用，而这里连续三个明字，不可谓不大胆。明月二字定是连着的，那前面两个明明呢？我们知道现代汉语中，”<strong>明明</strong>“有显然的意思。还暗含了一种不忿的情绪。“我明明可以做到的”。</p><p>然而在那时，显然没有这个用法，却并不影响我这么主观的理解。</p><p><strong>艺术作品，一半的完成是作家，另一半则是欣赏者</strong></p><p>“明明月亮才是我的前身啊”</p><p>这一句话暗藏了多少喟叹，不甘，艳羡，悔恨。却在最终只化作一句，明月是前身。</p><p>就像一个失去自由的人看到飞鸟，“我应当是这只飞鸟啊”。</p><p>到这个境界，已经是欲说还休了，人们不再诉说自己的痛苦，不再写下自己在绝境中的幻想，不再悔恨曾经，只是轻飘飘的一句话。<strong>是岁月积淀下的，浅而深的悲凉。</strong></p><p>我思绪开始游荡，词人是怀着怎样的心境，去向往明月，是怎样的经历让它不眷恋这人间，偏爱清冷高悬的月。这是一个怎样理想而清高的人，在俗世受了怎样的磋磨，才要回到天上去。</p><p>此时我的心中也罩上了一层淡淡的悲，因为有时我也会想，也许我不属于这人间吧，<strong>去当一粒星，一片云，流水中的一滴。只是活着，注视这世间，再不吞咽这许多意义。</strong></p><p>偏在此时，词人笔锋转了。</p><p>“回头成一笑，清冷几千春”。（未完待续）</p>]]></content>
      
      
      <categories>
          
          <category> 创作 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 诗词 </tag>
            
            <tag> 摘录 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>dfs专题</title>
      <link href="/2025/11/21/dfs/"/>
      <url>/2025/11/21/dfs/</url>
      
        <content type="html"><![CDATA[        <h1 id="指数型dfs-选或不选"   >          <a href="#指数型dfs-选或不选" class="heading-link"><i class="fas fa-link"></i></a><a href="#指数型dfs-选或不选" class="headerlink" title="指数型dfs(选或不选)"></a>指数型dfs(选或不选)</h1>      <ul><li>参数 ： 前u个数 选 or 不选 的</li><li><strong>需要保存第x位置的状态的时候就需要用st数组来存状态</strong></li><li>int st[] 0：没有遇见 1 选 2不选</li></ul><p>代码模板</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;cstring&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;algorithm&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">16</span>;</span><br><span class="line"><span class="type">int</span> st[N]; </span><br><span class="line"><span class="type">int</span> n;</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span> <span class="params">(<span class="type">int</span> u)</span> </span>&#123;<span class="comment">//u ：层数</span></span><br><span class="line">  <span class="keyword">if</span> (u &gt; n) &#123;<span class="comment">//叶子结点</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;=n; i ++ )&#123;</span><br><span class="line">      <span class="keyword">if</span> (st[i] == <span class="number">1</span>) &#123;<span class="comment">//如果选了 就输出 1选 2不选</span></span><br><span class="line">        cout &lt;&lt; i &lt;&lt; <span class="string">&#x27; &#x27;</span>;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">puts</span>(<span class="string">&quot;&quot;</span>);</span><br><span class="line">    <span class="keyword">return</span> ;</span><br><span class="line">  &#125;</span><br><span class="line"> </span><br><span class="line">  st [u] = <span class="number">1</span>;<span class="comment">//选</span></span><br><span class="line">  <span class="built_in">dfs</span> (u + <span class="number">1</span>);<span class="comment">//递归下一层</span></span><br><span class="line">  st[u] = <span class="number">0</span>;<span class="comment">//回溯</span></span><br><span class="line">  </span><br><span class="line">   st[u] = <span class="number">2</span>;<span class="comment">//不选</span></span><br><span class="line">  <span class="built_in">dfs</span> (u<span class="number">+1</span>);<span class="comment">//递归下一层</span></span><br><span class="line">  st[u] = <span class="number">0</span>;<span class="comment">//回溯 【恢复现场】 </span></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span> <span class="params">()</span> </span>&#123;</span><br><span class="line">  cin &gt;&gt; n;</span><br><span class="line">  <span class="built_in">dfs</span>(<span class="number">1</span>);</span><br><span class="line">  <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="烤鸡"   >          <a href="#烤鸡" class="heading-link"><i class="fas fa-link"></i></a><a href="#烤鸡" class="headerlink" title="烤鸡"></a>烤鸡</h2>      <p><span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/P2089" >P2089 烤鸡 - 洛谷</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>        <h3 id="题意"   >          <a href="#题意" class="heading-link"><i class="fas fa-link"></i></a><a href="#题意" class="headerlink" title="题意"></a>题意</h3>      <p>10 种配料，每种可以放 <strong>1~3 克</strong>，总美味程度 &#x3D; 所有配料质量之和 &#x3D; n，输出所有可能的配方数和配方（按字典序）没有方案则输出 0</p>        <h3 id="思路"   >          <a href="#思路" class="heading-link"><i class="fas fa-link"></i></a><a href="#思路" class="headerlink" title="思路"></a>思路</h3>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> n;</span><br><span class="line"><span class="type">int</span> a[<span class="number">11</span>];  <span class="comment">// a[1]~a[10] 存储配料</span></span><br><span class="line"><span class="type">int</span> cnt = <span class="number">0</span>;</span><br><span class="line"><span class="type">int</span> m[<span class="number">60000</span>][<span class="number">11</span>];  <span class="comment">// 第二维只需要11</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> x, <span class="type">int</span> sum)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (sum &gt; n) <span class="keyword">return</span>;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">if</span> (x &gt; <span class="number">10</span>) &#123;  <span class="comment">// 处理完10种配料</span></span><br><span class="line">        <span class="keyword">if</span> (sum == n) &#123;</span><br><span class="line">            cnt++;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= <span class="number">10</span>; i++) &#123;</span><br><span class="line">                m[cnt][i] = a[i];</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= <span class="number">3</span>; i++) &#123;</span><br><span class="line">        a[x] = i;</span><br><span class="line">        <span class="built_in">dfs</span>(x + <span class="number">1</span>, sum + i);</span><br><span class="line">        a[x] = <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    ios_base::<span class="built_in">sync_with_stdio</span>(<span class="literal">false</span>);</span><br><span class="line">    cin.<span class="built_in">tie</span>(<span class="literal">NULL</span>);</span><br><span class="line">    cout.<span class="built_in">tie</span>(<span class="literal">NULL</span>);</span><br><span class="line">    </span><br><span class="line">    cin &gt;&gt; n;</span><br><span class="line">    <span class="built_in">dfs</span>(<span class="number">1</span>, <span class="number">0</span>);  <span class="comment">// 从第1种配料开始</span></span><br><span class="line">    </span><br><span class="line">    cout &lt;&lt; cnt &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= cnt; i++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">1</span>; j &lt;= <span class="number">10</span>; j++) &#123;</span><br><span class="line">            cout &lt;&lt; m[i][j] &lt;&lt; <span class="string">&quot; &quot;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        cout &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="PERKET"   >          <a href="#PERKET" class="heading-link"><i class="fas fa-link"></i></a><a href="#PERKET" class="headerlink" title="PERKET"></a>PERKET</h2>      <p>[P2036 <span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/P2036" >COCI 2008&#x2F;2009 #2] PERKET - 洛谷</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>        <h3 id="题意-1"   >          <a href="#题意-1" class="heading-link"><i class="fas fa-link"></i></a><a href="#题意-1" class="headerlink" title="题意"></a>题意</h3>      <p>你有 <code>n</code> 种配料，每种可以<strong>选</strong>或<strong>不选</strong>，但不能全不选。<br>对于选中的配料：</p><ul><li>总酸度 &#x3D; 选中配料的酸度的<strong>乘积</strong></li><li>总苦度 &#x3D; 选中配料的苦度的<strong>总和</strong></li><li>目标是 <code>min(|酸度 - 苦度|)</code></li></ul>        <h3 id="思路-1"   >          <a href="#思路-1" class="heading-link"><i class="fas fa-link"></i></a><a href="#思路-1" class="headerlink" title="思路"></a>思路</h3>      <p>由于每个调料可选可不选，我们可以用一个st数组判断状态，1表示选，2表示不选。最后计算的时候遍历数组，只有st[i]&#x3D;&#x3D;1时才计算s,b。</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">int</span> n;</span><br><span class="line"><span class="type">int</span> s, b;</span><br><span class="line"><span class="type">int</span> st[<span class="number">200</span>];</span><br><span class="line"><span class="type">int</span> res = <span class="number">1e9</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">node</span>&#123;</span><br><span class="line">    <span class="type">int</span> s, b;</span><br><span class="line">&#125; a[<span class="number">20</span>];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> x)</span> </span>&#123;</span><br><span class="line">    <span class="type">bool</span> has= <span class="literal">false</span>;  <span class="comment">// 标记是否存在至少一个被选中的元素</span></span><br><span class="line">    <span class="keyword">if</span> (x &gt; n) &#123;</span><br><span class="line">        <span class="type">int</span> sum1 = <span class="number">1</span>;  <span class="comment">// 计算选中元素的s属性乘积</span></span><br><span class="line">        <span class="type">int</span> sum2 = <span class="number">0</span>;  <span class="comment">// 计算选中元素的b属性和</span></span><br><span class="line">        </span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (st[i] == <span class="number">1</span>) &#123;  <span class="comment">// 如果元素被选中</span></span><br><span class="line">                has = <span class="literal">true</span>;     <span class="comment">// 标记存在选中元素</span></span><br><span class="line">                sum1 *= a[i].s; <span class="comment">// 累乘s属性</span></span><br><span class="line">                sum2 += a[i].b; <span class="comment">// 累加b属性</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 如果存在至少一个选中的元素，更新结果</span></span><br><span class="line">        <span class="keyword">if</span> (has) &#123;</span><br><span class="line">            res = <span class="built_in">min</span>(res, <span class="built_in">abs</span>(sum1 - sum2));  <span class="comment">// 更新最小差值</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">  &#125;</span><br><span class="line">    <span class="comment">// 递归处理：选择当前元素</span></span><br><span class="line">  st[x] = <span class="number">1</span>;</span><br><span class="line">  <span class="built_in">dfs</span>(x + <span class="number">1</span>);</span><br><span class="line">  st[x] = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 递归处理：不选择当前元素</span></span><br><span class="line">  st[x] = <span class="number">2</span>;</span><br><span class="line">  <span class="built_in">dfs</span>(x + <span class="number">1</span>);</span><br><span class="line">  st[x] = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    ios_base::<span class="built_in">sync_with_stdio</span>(<span class="literal">false</span>);</span><br><span class="line">    cin.<span class="built_in">tie</span>(<span class="literal">NULL</span>);</span><br><span class="line">    cout.<span class="built_in">tie</span>(<span class="literal">NULL</span>);</span><br><span class="line">    cin &gt;&gt; n;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n;i++)&#123;</span><br><span class="line">      cin &gt;&gt;a[i].s &gt;&gt; a[i].b;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">dfs</span>(<span class="number">1</span>);</span><br><span class="line">    cout &lt;&lt; res &lt;&lt; endl;</span><br><span class="line">   </span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>当然还有一种写法。直接多往dfs里面传参</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">int</span> n;</span><br><span class="line"><span class="type">int</span> s[<span class="number">15</span>], b[<span class="number">15</span>];</span><br><span class="line"><span class="type">int</span> ans = <span class="number">1e9</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> index, <span class="type">int</span> total_s, <span class="type">int</span> total_b, <span class="type">bool</span> chosen)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (index == n) &#123;</span><br><span class="line">        <span class="keyword">if</span> (chosen) &#123;</span><br><span class="line">            ans = <span class="built_in">min</span>(ans, <span class="built_in">abs</span>(total_s - total_b));</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 不选当前配料</span></span><br><span class="line">    <span class="built_in">dfs</span>(index + <span class="number">1</span>, total_s, total_b, chosen);</span><br><span class="line">    <span class="comment">// 选当前配料</span></span><br><span class="line">    <span class="built_in">dfs</span>(index + <span class="number">1</span>, total_s * s[index], total_b + b[index], <span class="literal">true</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    cin &gt;&gt; n;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">        cin &gt;&gt; s[i] &gt;&gt; b[i];</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="built_in">dfs</span>(<span class="number">0</span>, <span class="number">1</span>, <span class="number">0</span>, <span class="literal">false</span>);</span><br><span class="line">    </span><br><span class="line">    cout &lt;&lt; ans &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="全排列型dfs"   >          <a href="#全排列型dfs" class="heading-link"><i class="fas fa-link"></i></a><a href="#全排列型dfs" class="headerlink" title="全排列型dfs"></a>全排列型dfs</h1>      <p>大概是每个位置要选什么数字，模板如下</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">10</span>;</span><br><span class="line"><span class="type">int</span> path[N];<span class="comment">//保存序列</span></span><br><span class="line"><span class="type">int</span> state[N];<span class="comment">//数字是否被用过</span></span><br><span class="line"><span class="type">int</span> n;</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> u)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(u &gt; n)<span class="comment">//数字填完了，输出</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++)<span class="comment">//输出方案</span></span><br><span class="line">            cout &lt;&lt; path[i] &lt;&lt; <span class="string">&quot; &quot;</span>;</span><br><span class="line">        cout &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++)<span class="comment">//空位上可以选择的数字为:1 ~ n</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span>(!state[i])<span class="comment">//如果数字 i 没有被用过</span></span><br><span class="line">        &#123;</span><br><span class="line">            path[u] = i;<span class="comment">// 放入空位</span></span><br><span class="line">            state[i] = <span class="number">1</span>;<span class="comment">//数字被用，修改状态</span></span><br><span class="line">            <span class="built_in">dfs</span>(u + <span class="number">1</span>);<span class="comment">//填下一个位</span></span><br><span class="line">            state[i] = <span class="number">0</span>;<span class="comment">//回溯，取出 i</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    cin &gt;&gt; n;</span><br><span class="line">    <span class="built_in">dfs</span>(<span class="number">1</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>先来一道模板题</p>        <h2 id="全排列问题"   >          <a href="#全排列问题" class="heading-link"><i class="fas fa-link"></i></a><a href="#全排列问题" class="headerlink" title="全排列问题"></a>全排列问题</h2>      <p><span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/P1706" >P1706 全排列问题 - 洛谷</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>        <h3 id="题意-2"   >          <a href="#题意-2" class="heading-link"><i class="fas fa-link"></i></a><a href="#题意-2" class="headerlink" title="题意"></a>题意</h3>      <p>按照字典序输出自然数 1 到 <em>n</em> 所有不重复的排列，即 <em>n</em> 的全排列，要求所产生的任一数字序列中不允许出现重复的数字。</p>        <h3 id="思路-2"   >          <a href="#思路-2" class="heading-link"><i class="fas fa-link"></i></a><a href="#思路-2" class="headerlink" title="思路"></a>思路</h3>      <p>好像没什么好说的，太模板了</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> n;</span><br><span class="line"><span class="type">int</span> a[<span class="number">100</span>];</span><br><span class="line"><span class="type">bool</span> vis[<span class="number">100</span>];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> x)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (x &gt; n) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">&quot;%5d&quot;</span>, a[i]); </span><br><span class="line">        &#125;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;\n&quot;</span>);  </span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!vis[i]) &#123;</span><br><span class="line">            a[x] = i;</span><br><span class="line">            vis[i] = <span class="literal">true</span>;</span><br><span class="line">            <span class="built_in">dfs</span>(x + <span class="number">1</span>);</span><br><span class="line">            vis[i] = <span class="literal">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    cin &gt;&gt; n;</span><br><span class="line">    <span class="built_in">dfs</span>(<span class="number">1</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="火星人"   >          <a href="#火星人" class="heading-link"><i class="fas fa-link"></i></a><a href="#火星人" class="headerlink" title="火星人"></a>火星人</h2>      <p>[P1088 <span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/P1088" >NOIP 2004 普及组] 火星人 - 洛谷</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>        <h3 id="题意-3"   >          <a href="#题意-3" class="heading-link"><i class="fas fa-link"></i></a><a href="#题意-3" class="headerlink" title="题意"></a>题意</h3>      <p>由1-n（不重复）组成的全排列数里，有a,b，假设全排列数列已经sort好，你要找到中找到a后面的第b个数。</p>        <h3 id="思路-3"   >          <a href="#思路-3" class="heading-link"><i class="fas fa-link"></i></a><a href="#思路-3" class="headerlink" title="思路"></a>思路</h3>      <p>这道题的本质就是全排列，如果不考虑数据范围的话，直接这么写</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> n, m;</span><br><span class="line">vector&lt;vector&lt;<span class="type">int</span>&gt;&gt; all;  <span class="comment">// 存储所有排列</span></span><br><span class="line">vector&lt;<span class="type">int</span>&gt; cur;  <span class="comment">// 当前排列</span></span><br><span class="line"><span class="type">bool</span> vis[<span class="number">100</span>];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> x, vector&lt;<span class="type">int</span>&gt;&amp; temp)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (x &gt; n) &#123;</span><br><span class="line">        all.<span class="built_in">push_back</span>(temp);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!vis[i]) &#123;</span><br><span class="line">            vis[i] = <span class="literal">true</span>;</span><br><span class="line">            temp[x<span class="number">-1</span>] = i;  <span class="comment">// 索引从0开始</span></span><br><span class="line">            <span class="built_in">dfs</span>(x + <span class="number">1</span>, temp);</span><br><span class="line">            vis[i] = <span class="literal">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    ios_base::<span class="built_in">sync_with_stdio</span>(<span class="literal">false</span>);</span><br><span class="line">    cin.<span class="built_in">tie</span>(<span class="literal">NULL</span>);</span><br><span class="line">    cout.<span class="built_in">tie</span>(<span class="literal">NULL</span>);</span><br><span class="line">    </span><br><span class="line">    cin &gt;&gt; n &gt;&gt; m;</span><br><span class="line">    cur.<span class="built_in">resize</span>(n);</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 读入当前排列</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">        cin &gt;&gt; cur[i];</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 生成全排列</span></span><br><span class="line">    <span class="function">vector&lt;<span class="type">int</span>&gt; <span class="title">temp</span><span class="params">(n)</span></span>;</span><br><span class="line">    <span class="built_in">dfs</span>(<span class="number">1</span>, temp);</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 排序（vector默认按字典序比较）</span></span><br><span class="line">    <span class="built_in">sort</span>(all.<span class="built_in">begin</span>(), all.<span class="built_in">end</span>());</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 找到当前位置</span></span><br><span class="line">    <span class="type">int</span> pos = <span class="number">-1</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; all.<span class="built_in">size</span>(); i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (all[i] == cur) &#123;</span><br><span class="line">            pos = i;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 输出新排列</span></span><br><span class="line">    vector&lt;<span class="type">int</span>&gt; result = all[pos + m];</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">        cout &lt;&lt; result[i];</span><br><span class="line">        <span class="keyword">if</span> (i &lt; n - <span class="number">1</span>) cout &lt;&lt; <span class="string">&quot; &quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    cout &lt;&lt; endl;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>注意到题目N&lt;10000，那枚举会达到恐怖的10000!。所以这段代码你交上去只能得20分。其他的MLE了。</p><p>剪枝好像也没有什么操作空间。</p><p>这时候不得不提到STL的喵喵小工具。</p><p><strong>我们可以利用 C++ STL 的 <code>next_permutation</code> 函数来高效解决。</strong></p>        <h4 id="next-permutation-工作原理"   >          <a href="#next-permutation-工作原理" class="heading-link"><i class="fas fa-link"></i></a><a href="#next-permutation-工作原理" class="headerlink" title="next_permutation 工作原理"></a><code>next_permutation</code> 工作原理</h4>      <ol><li>从右向左找到第一个升序对 <code>(i, i+1)</code>，满足 <code>a[i] &lt; a[i+1]</code></li><li>从右向左找到第一个大于 <code>a[i]</code> 的元素 <code>a[j]</code></li><li>交换 <code>a[i]</code> 和 <code>a[j]</code></li><li>将 <code>a[i+1]</code> 到末尾的元素反转</li></ol>        <h4 id="时间复杂度"   >          <a href="#时间复杂度" class="heading-link"><i class="fas fa-link"></i></a><a href="#时间复杂度" class="headerlink" title="时间复杂度"></a>时间复杂度</h4>      <ul><li>每次 <code>next_permutation</code> 操作：O(N)</li><li>总共 M 次操作：O(N × M)</li><li>在 N≤10000, M≤100 时完全可行</li></ul><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 读入当前排列</span></span><br><span class="line"><span class="function">vector&lt;<span class="type">int</span>&gt; <span class="title">fingers</span><span class="params">(n)</span></span>;</span><br><span class="line"><span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">    cin &gt;&gt; fingers[i];</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 next_permutation 找第 m 个后续排列</span></span><br><span class="line"><span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; m; i++) &#123;</span><br><span class="line">    <span class="built_in">next_permutation</span>(fingers.<span class="built_in">begin</span>(), fingers.<span class="built_in">end</span>());</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>就是如此简单，附上AC代码</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="type">int</span> n, m;</span><br><span class="line">    cin &gt;&gt; n &gt;&gt; m;</span><br><span class="line">    </span><br><span class="line">    <span class="function">vector&lt;<span class="type">int</span>&gt; <span class="title">fingers</span><span class="params">(n)</span></span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">        cin &gt;&gt; fingers[i];</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 使用 next_permutation 找第 m 个后续排列</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; m; i++) &#123;</span><br><span class="line">        <span class="built_in">next_permutation</span>(fingers.<span class="built_in">begin</span>(), fingers.<span class="built_in">end</span>());</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 输出结果</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">        cout &lt;&lt; fingers[i];</span><br><span class="line">        <span class="keyword">if</span> (i &lt; n - <span class="number">1</span>) cout &lt;&lt; <span class="string">&quot; &quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    cout &lt;&lt; endl;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="组合型dfs"   >          <a href="#组合型dfs" class="heading-link"><i class="fas fa-link"></i></a><a href="#组合型dfs" class="headerlink" title="组合型dfs"></a>组合型dfs</h1>      <ul><li><strong>与全排列的差别就是第二个for循环开始的位置，换句话说就是每个数该放什么位置。</strong></li></ul><p>模板如下</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">30</span>;</span><br><span class="line"><span class="type">int</span> path[N];</span><br><span class="line"><span class="type">int</span> n, m;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span> <span class="params">(<span class="type">int</span> u, <span class="type">int</span> start )</span> </span>&#123;<span class="comment">//u:层数  start：起始的数值</span></span><br><span class="line">    <span class="keyword">if</span> (u &gt; m) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= m; i ++ ) &#123;</span><br><span class="line">            cout &lt;&lt; path[i] &lt;&lt; <span class="string">&#x27; &#x27;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="built_in">puts</span>(<span class="string">&quot;&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = start; i &lt;= n; i ++) &#123;<span class="comment">//</span></span><br><span class="line">            path[u] = i;<span class="comment">//表示已经填了</span></span><br><span class="line">            <span class="built_in">dfs</span>(u + <span class="number">1</span>, i + <span class="number">1</span>);<span class="comment">//递归下一层</span></span><br><span class="line">            path[u] = <span class="number">0</span>;<span class="comment">//恢复现场</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125; </span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span> <span class="params">()</span> </span>&#123;</span><br><span class="line">    cin &gt;&gt; n &gt;&gt; m;</span><br><span class="line">    <span class="built_in">dfs</span>(<span class="number">1</span>,<span class="number">1</span>); <span class="comment">//第一层开始  且从1开始枚举</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></div></figure>        <h2 id="选数"   >          <a href="#选数" class="heading-link"><i class="fas fa-link"></i></a><a href="#选数" class="headerlink" title="选数"></a>选数</h2>      <p>[P1036 <span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/P1036#submit" >NOIP 2002 普及组] 选数 - 洛谷</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>        <h3 id="题意-4"   >          <a href="#题意-4" class="heading-link"><i class="fas fa-link"></i></a><a href="#题意-4" class="headerlink" title="题意"></a>题意</h3>      <p>已知 <em>n</em> 个整数 <em>x</em>1,<em>x</em>2,⋯,<em>x**n</em>，以及 1 个整数 <em>k</em>（<em>k</em>&lt;<em>n</em>）。从 <em>n</em> 个整数中任选 <em>k</em> 个整数相加，可分别得到一系列的和。求和为素数的有多少种</p>        <h3 id="思路-4"   >          <a href="#思路-4" class="heading-link"><i class="fas fa-link"></i></a><a href="#思路-4" class="headerlink" title="思路"></a>思路</h3>      <p>对于这个dfs的状态，三点就可以描述</p><ul><li><code>idx</code>：知道处理到哪了</li><li><code>cnt</code>：知道选了几个</li><li><code>sum</code>：知道当前和是多少</li></ul><p>对于每个位置idx，有选和不选两种选择，如果选择</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">dfs</span>(idx + <span class="number">1</span>, cnt + <span class="number">1</span>, sum + a[idx]);<span class="comment">//移到下一个数，选择数量加一，和增加</span></span><br></pre></td></tr></table></div></figure><p>如果不选</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">dfs</span>(idx + <span class="number">1</span>, cnt, sum);</span><br></pre></td></tr></table></div></figure><p>写dfs除了状态参数，第一个写的就是终止状态，什么时候终止呢，idx&gt;n时说明已经考虑完所有数字了。但是此时还必须刚好选择k个元素，然后还要检查和是否为素数</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (idx &gt; n) &#123;</span><br><span class="line">    <span class="keyword">if</span> (cnt == k &amp;&amp; <span class="built_in">is_prime</span>(sum)) &#123;</span><br><span class="line">        ans++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="代码"   >          <a href="#代码" class="heading-link"><i class="fas fa-link"></i></a><a href="#代码" class="headerlink" title="代码"></a>代码</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> n, k;</span><br><span class="line"><span class="type">int</span> a[<span class="number">25</span>];</span><br><span class="line"><span class="type">int</span> ans = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">bool</span> <span class="title">is_prime</span><span class="params">(<span class="type">int</span> x)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (x &lt; <span class="number">2</span>) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">2</span>; i * i &lt;= x; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (x % i == <span class="number">0</span>) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> idx, <span class="type">int</span> cnt, <span class="type">int</span> sum)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 已经考虑完所有元素</span></span><br><span class="line">    <span class="keyword">if</span> (idx &gt; n) &#123;</span><br><span class="line">        <span class="comment">// 必须正好选择k个元素且和为素数</span></span><br><span class="line">        <span class="keyword">if</span> (cnt == k &amp;&amp; <span class="built_in">is_prime</span>(sum)) &#123;</span><br><span class="line">            ans++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 选择1：选取当前元素（前提是还没选够k个）</span></span><br><span class="line">    <span class="keyword">if</span> (cnt &lt; k) &#123;</span><br><span class="line">        <span class="built_in">dfs</span>(idx + <span class="number">1</span>, cnt + <span class="number">1</span>, sum + a[idx]);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 选择2：不选取当前元素</span></span><br><span class="line">    <span class="built_in">dfs</span>(idx + <span class="number">1</span>, cnt, sum);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    cin &gt;&gt; n &gt;&gt; k;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        cin &gt;&gt; a[i];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">dfs</span>(<span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>);</span><br><span class="line">    cout &lt;&lt; ans;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="奇怪的电梯"   >          <a href="#奇怪的电梯" class="heading-link"><i class="fas fa-link"></i></a><a href="#奇怪的电梯" class="headerlink" title="奇怪的电梯"></a>奇怪的电梯</h1>      <p><span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/P1135" >P1135 奇怪的电梯 - 洛谷</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>        <h2 id="题意-5"   >          <a href="#题意-5" class="heading-link"><i class="fas fa-link"></i></a><a href="#题意-5" class="headerlink" title="题意"></a>题意</h2>      <p>有一栋 <code>N</code> 层的大楼，每层楼有一个数字 <code>K_i</code>，电梯有四个按钮：开、关、上、下。按”上”会移动到 <code>当前楼层 + K_当前楼层</code>，按”下”会移动到 <code>当前楼层 - K_当前楼层</code>。要求从 <code>A</code> 楼到达 <code>B</code> 楼，求最少需要按几次按钮，如果无法到达则输出 <code>-1</code>。</p>        <h2 id="思路-5"   >          <a href="#思路-5" class="heading-link"><i class="fas fa-link"></i></a><a href="#思路-5" class="headerlink" title="思路"></a>思路</h2>      <p>这是一个典型的最短路径搜索问题。我们可以把每个楼层看作图中的一个节点，每个合法的上下移动看作图中的边，问题就转化为了从节点 <code>A</code> 到节点 <code>B</code> 的最短路径问题。仍然是思考，状态表示，搜索过程，终止条件，以及回溯。</p><p><strong>DFS 的设计思路：</strong></p><ul><li><strong>状态表示</strong>：<code>(当前楼层, 已按按钮次数)</code></li><li><strong>搜索过程</strong>：从起点 <code>A</code> 开始，每次尝试向上或向下移动</li><li><strong>终止条件</strong>：到达目标楼层 <code>B</code></li><li><strong>回溯机制</strong>：尝试完一个方向后要取消标记，以便探索其他路径</li></ul><p>至于题目提到的有时按钮超过上下限就会失灵的情况，我们只需要每次递归前判断一次一次即可。因为我们知道当前楼层，也就知道当前楼层要移动的距离k[h]。</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> h, <span class="type">int</span> cnt)</span> </span>&#123;  </span><br><span class="line">    <span class="keyword">if</span>(cnt &gt;= min1) <span class="keyword">return</span>;<span class="comment">//如果超过了当前最小方案数，直接跳过剪枝</span></span><br><span class="line">    <span class="keyword">if</span>(h == b)&#123;</span><br><span class="line">        min1 = <span class="built_in">min</span>(min1, cnt);<span class="comment">//到达指定楼层记录最小方案数</span></span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    vis[h] = <span class="literal">true</span>;<span class="comment">//标记已经访问</span></span><br><span class="line"></span><br><span class="line">    <span class="type">int</span> up = h + k[h];<span class="comment">//上楼</span></span><br><span class="line">    <span class="keyword">if</span>(up &lt;= n &amp;&amp; !vis[up]) &#123;</span><br><span class="line">        <span class="built_in">dfs</span>(up, cnt + <span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="type">int</span> down = h - k[h];<span class="comment">//下楼</span></span><br><span class="line">    <span class="keyword">if</span>(down &gt;= <span class="number">1</span> &amp;&amp; !vis[down]) &#123;</span><br><span class="line">        <span class="built_in">dfs</span>(down, cnt + <span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    vis[h] = <span class="literal">false</span>;<span class="comment">//回溯</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></div></figure><p>如果你这么写那就喜提超时了。我们继续思考剪枝优化，我们最开始的剪枝，是遍历到超过所有的最小方案数再剪枝。要进一步优化的话，就每到一层剪一次枝。我们用一个数组记录到达当前楼层的最小方案数。如果回溯过程中超过了，直接return。</p>        <h2 id="代码-1"   >          <a href="#代码-1" class="heading-link"><i class="fas fa-link"></i></a><a href="#代码-1" class="headerlink" title="代码"></a>代码</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">int</span> n,a,b;</span><br><span class="line"><span class="type">bool</span> vis[<span class="number">210</span>];</span><br><span class="line"><span class="type">int</span> min1 = <span class="number">1e9</span>;</span><br><span class="line"><span class="type">int</span> k[<span class="number">210</span>];</span><br><span class="line"><span class="type">int</span> dist[<span class="number">210</span>];  <span class="comment">// 新增：记录到达每层的最小步数</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> h, <span class="type">int</span> cnt)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 重要剪枝1：如果当前步数已经大于等于已知最优解，直接返回</span></span><br><span class="line">    <span class="keyword">if</span>(cnt &gt;= min1) <span class="keyword">return</span>;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 重要剪枝2：如果当前步数已经大于等于到达这层的历史最小步数，直接返回</span></span><br><span class="line">    <span class="keyword">if</span>(cnt &gt;= dist[h]) <span class="keyword">return</span>;</span><br><span class="line">    dist[h] = cnt;  <span class="comment">// 更新到达这层的最小步数</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">if</span>(h == b)&#123;</span><br><span class="line">        min1 = <span class="built_in">min</span>(min1, cnt);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    vis[h] = <span class="literal">true</span>;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 向上移动</span></span><br><span class="line">    <span class="type">int</span> up = h + k[h];</span><br><span class="line">    <span class="keyword">if</span>(up &lt;= n &amp;&amp; !vis[up]) &#123;</span><br><span class="line">        <span class="built_in">dfs</span>(up, cnt + <span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 向下移动</span></span><br><span class="line">    <span class="type">int</span> down = h - k[h];</span><br><span class="line">    <span class="keyword">if</span>(down &gt;= <span class="number">1</span> &amp;&amp; !vis[down]) &#123;</span><br><span class="line">        <span class="built_in">dfs</span>(down, cnt + <span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    vis[h] = <span class="literal">false</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    ios_base::<span class="built_in">sync_with_stdio</span>(<span class="literal">false</span>);</span><br><span class="line">    cin.<span class="built_in">tie</span>(<span class="literal">NULL</span>);</span><br><span class="line">    cout.<span class="built_in">tie</span>(<span class="literal">NULL</span>);</span><br><span class="line">    cin &gt;&gt; n &gt;&gt; a &gt;&gt; b;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        cin &gt;&gt; k[i];</span><br><span class="line">        dist[i] = <span class="number">1e9</span>;  <span class="comment">// 初始化最小步数为无穷大</span></span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="built_in">dfs</span>(a, <span class="number">0</span>);</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">if</span>(min1 == <span class="number">1e9</span>) </span><br><span class="line">        cout &lt;&lt; <span class="number">-1</span>;</span><br><span class="line">    <span class="keyword">else</span> </span><br><span class="line">        cout &lt;&lt; min1;</span><br><span class="line">        </span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>其实这道题还可以bfs，后面再补吧。</p>        <h1 id="自然数的拆分问题"   >          <a href="#自然数的拆分问题" class="heading-link"><i class="fas fa-link"></i></a><a href="#自然数的拆分问题" class="headerlink" title="自然数的拆分问题"></a>自然数的拆分问题</h1>      <p><span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/P2404" >P2404 自然数的拆分问题 - 洛谷</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>        <h2 id="题意-6"   >          <a href="#题意-6" class="heading-link"><i class="fas fa-link"></i></a><a href="#题意-6" class="headerlink" title="题意"></a>题意</h2>      <p>现在给你一个自然数 <em>n</em>，要求你求出 <em>n</em> 的拆分成一些数字的和。每个拆分后的序列中的数字从小到大排序。字典序小的优先输出</p>        <h2 id="思路-6"   >          <a href="#思路-6" class="heading-link"><i class="fas fa-link"></i></a><a href="#思路-6" class="headerlink" title="思路"></a>思路</h2>      <p>关于dfs的构建，我们需要三个关键状态：</p><ul><li><strong>当前序列</strong> (<code>vector&lt;int&gt; v</code>)：记录已经选择的数字</li><li><strong>当前和</strong> (<code>int sum</code>)：已选数字的总和</li><li><strong>起始数字</strong> (<code>int start</code>)：下一个数字的最小值（保证递增和字典序）</li></ul>        <h3 id="搜索过程"   >          <a href="#搜索过程" class="heading-link"><i class="fas fa-link"></i></a><a href="#搜索过程" class="headerlink" title="搜索过程"></a>搜索过程</h3>      <ol><li><strong>从数字 1 开始</strong>，这是最小的可能数字</li><li><strong>对于每个数字 i</strong>，尝试将其加入当前序列</li><li><strong>递归搜索</strong>：以 i 作为新的起始数字（保证后续数字 ≥ 当前数字）</li><li><strong>回溯</strong>：撤销当前选择，尝试其他可能性</li></ol>        <h2 id="代码-2"   >          <a href="#代码-2" class="heading-link"><i class="fas fa-link"></i></a><a href="#代码-2" class="headerlink" title="代码"></a>代码</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">int</span> n;</span><br><span class="line">vector&lt;<span class="type">int</span>&gt; v;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> start, <span class="type">int</span> sum)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (sum == n) &#123;</span><br><span class="line">        <span class="keyword">if</span>(v.<span class="built_in">size</span>() == <span class="number">1</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; v.<span class="built_in">size</span>(); i++) &#123;</span><br><span class="line">            cout &lt;&lt; v[i];</span><br><span class="line">            <span class="keyword">if</span> (i &lt; v.<span class="built_in">size</span>() - <span class="number">1</span>) cout &lt;&lt; <span class="string">&quot;+&quot;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        cout &lt;&lt; endl;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = start; i &lt;= n - sum; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (sum + i &lt;= n) &#123;</span><br><span class="line">            v.<span class="built_in">push_back</span>(i);</span><br><span class="line">            <span class="built_in">dfs</span>(i, sum + i);  <span class="comment">//注意，同一个数字可以多次使用，所以不是i+1而是i</span></span><br><span class="line">            v.<span class="built_in">pop_back</span>();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    ios_base::<span class="built_in">sync_with_stdio</span>(<span class="literal">false</span>);</span><br><span class="line">    cin.<span class="built_in">tie</span>(<span class="literal">NULL</span>);</span><br><span class="line">    cout.<span class="built_in">tie</span>(<span class="literal">NULL</span>);</span><br><span class="line">    </span><br><span class="line">    cin &gt;&gt; n;</span><br><span class="line">    <span class="built_in">dfs</span>(<span class="number">1</span>, <span class="number">0</span>);  <span class="comment">// 从数字1开始，当前和为0</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="八皇后问题"   >          <a href="#八皇后问题" class="heading-link"><i class="fas fa-link"></i></a><a href="#八皇后问题" class="headerlink" title="八皇后问题"></a>八皇后问题</h1>      <p><span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/P1219" >洛谷USACO1.5八皇后</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>        <h2 id="题意-7"   >          <a href="#题意-7" class="heading-link"><i class="fas fa-link"></i></a><a href="#题意-7" class="headerlink" title="题意"></a>题意</h2>      <p>nxn的棋盘，同一行和同一列不可以有两个棋子，且每条对角线都至多有一个棋子。让你给出三种解法里面的列标，以及最后的解法数。</p>        <h2 id="思路-7"   >          <a href="#思路-7" class="heading-link"><i class="fas fa-link"></i></a><a href="#思路-7" class="headerlink" title="思路"></a>思路</h2>      <p>非常典型的dfs回溯问题。唯一需要思考的，是我该怎么回溯。怎么来构建这个dfs图。</p><p>很朴素经典的dfs思想是，从第一行开始放棋，对于每一行，尝试完所有的位置，尝试完后到下一行。检查每个位置是否满足条件，满足就标记且占用，而且递归处理下一行。（记得要回溯尝试其他可能，要取消标记和占用）那么行数其实就是这个dfs树的深度（dep）了。你的脑子里应该马上有这一段。</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> dep)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(dep==n<span class="number">+1</span>)&#123;</span><br><span class="line">        </span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">1</span>;i&lt;=n;i++)&#123;</span><br><span class="line">        <span class="comment">//列的遍历</span></span><br><span class="line">        <span class="keyword">if</span>(check)&#123;</span><br><span class="line">            <span class="comment">//标记并记录</span></span><br><span class="line">            <span class="built_in">dfs</span>(dep<span class="number">+1</span>)<span class="comment">//递归</span></span><br><span class="line">       <span class="comment">// 回溯                  </span></span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>接下来就是完善细节。由于我们是一行一行遍历，找到符合条件的进入下一行**，所以完全不用担心一行会出现两**个棋子。所以我们需要考虑的只有对角线和每一列。注意我们还要标记每行里面放皇后的列号。因此我们需要两个数组来存储。<strong>vis数组看每列是否有访问，col数组存储每行放置棋子的列号。</strong></p><p>对于对角线，如果你第一次接触这个问题可能会想到用循环解决，事实上有着更简单的检查方法。</p><p><img src="/../images/image-20251121171812054.png" alt="image-20251121171812054"></p><p><strong>对于主对角线</strong>，我们不难发现，<strong>行-列一定是一个同样的数字。</strong></p><p><strong>对于副对角线</strong>，我们也可以发现，列＋行也是一个同样的数字</p><p><img src="/../images/image-20251121171925635.png" alt="image-20251121171925635"></p><p>举个例子，如果我在（2，4）放了棋子</p><p><img src="/../images/image-20251121171952903.png" alt="image-20251121171952903"></p><p><strong>但是涉及到减号我们就要格外注意数组越界</strong>，因为行-列并不总是正数。</p><p>这里我们不需要边界检查，只需要用到一个常用的偏移技巧就好。都加上n。（不细说了自行脑补）</p>        <h2 id="代码-3"   >          <a href="#代码-3" class="heading-link"><i class="fas fa-link"></i></a><a href="#代码-3" class="headerlink" title="代码"></a>代码</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">20</span>;</span><br><span class="line"><span class="type">int</span> n, total = <span class="number">0</span>;</span><br><span class="line"><span class="type">int</span> col[N];          <span class="comment">// 存储每一行皇后所在的列号</span></span><br><span class="line"><span class="type">bool</span> vis[N];        <span class="comment">// 标记列是否被占用</span></span><br><span class="line"><span class="type">bool</span> diag1[<span class="number">2</span>*N];     <span class="comment">// 主对角线 (r - c + n)</span></span><br><span class="line"><span class="type">bool</span> diag2[<span class="number">2</span>*N];     <span class="comment">// 副对角线 (r + c)</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">print</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        cout &lt;&lt; col[i];</span><br><span class="line">        <span class="keyword">if</span> (i &lt; n) cout &lt;&lt; <span class="string">&quot; &quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    cout &lt;&lt; endl;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> dep)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (dep == n + <span class="number">1</span>) &#123;</span><br><span class="line">        total++;</span><br><span class="line">        <span class="keyword">if</span> (total &lt;= <span class="number">3</span>) &#123;</span><br><span class="line">            <span class="built_in">print</span>();<span class="comment">//只打印前三个解</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        <span class="comment">// 检查列和对角线是否被占用</span></span><br><span class="line">        <span class="keyword">if</span> (!vis[i] &amp;&amp; !diag1[dep - i + n] &amp;&amp; !diag2[dep + i]) &#123;</span><br><span class="line">            <span class="comment">// 放置皇后</span></span><br><span class="line">            <span class="comment">//标记主对角线是否被占用（r-i 可能为负数，所以 +n 偏移）</span></span><br><span class="line">            col[dep] = i;</span><br><span class="line">            vis[i] = <span class="literal">true</span>;</span><br><span class="line">            diag1[dep - i + n] = <span class="literal">true</span>;</span><br><span class="line">            diag2[dep + i] = <span class="literal">true</span>;</span><br><span class="line">            </span><br><span class="line">            <span class="comment">// 递归下一行</span></span><br><span class="line">            <span class="built_in">dfs</span>(dep + <span class="number">1</span>);</span><br><span class="line">            </span><br><span class="line">            <span class="comment">// 回溯</span></span><br><span class="line">            vis[i] = <span class="literal">false</span>;</span><br><span class="line">            diag1[dep - i + n] = <span class="literal">false</span>;</span><br><span class="line">            diag2[dep + i] = <span class="literal">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">solve</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    cin &gt;&gt; n;</span><br><span class="line">    <span class="built_in">dfs</span>(<span class="number">1</span>);</span><br><span class="line">    cout &lt;&lt; total &lt;&lt; endl;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    ios::<span class="built_in">sync_with_stdio</span>(<span class="number">0</span>), cin.<span class="built_in">tie</span>(<span class="number">0</span>), cout.<span class="built_in">tie</span>(<span class="number">0</span>);</span><br><span class="line">    <span class="built_in">solve</span>();</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="单词接龙"   >          <a href="#单词接龙" class="heading-link"><i class="fas fa-link"></i></a><a href="#单词接龙" class="headerlink" title="单词接龙"></a>单词接龙</h1>      <p><span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/P1019" >洛谷P1019 [NOIP 2000 提高组] 单词接龙（疑似错题）</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>        <h2 id="题意-8"   >          <a href="#题意-8" class="heading-link"><i class="fas fa-link"></i></a><a href="#题意-8" class="headerlink" title="题意"></a>题意</h2>      <p>你有 n 个单词，每个单词最多用两次。给定一个起始字母，要找出最长的“龙”。接龙规则是相邻单词必须有重合部分，但不能是包含关系。</p><p>比如 <code>beast</code> 接 <code>astonish</code>，重合 <code>&quot;ast&quot;</code>，变成 <code>beastonish</code>。</p>        <h2 id="思路-8"   >          <a href="#思路-8" class="heading-link"><i class="fas fa-link"></i></a><a href="#思路-8" class="headerlink" title="思路"></a>思路</h2>      <p>依旧典型的 DFS 回溯问题</p><p>依旧很朴素经典的 DFS 思想是：从起始字母的单词开始，对于当前龙字符串，尝试所有能接上的单词，接上后递归处理更长的龙，然后回溯尝试其他可能。</p><p>那么<strong>当前龙的长度</strong>其实就是这个 DFS 树的深度。理清楚下dfs的要点</p><ul><li><strong>状态</strong>：当前拼接的龙字符串 <code>tmp</code></li><li><strong>选择</strong>：所有使用次数 <code>&lt; 2</code> 且能与当前龙末尾重合的单词</li><li><strong>递归深度</strong>：龙的长度</li><li><strong>回溯</strong>：恢复单词使用次数</li></ul><p>这就是大概框架，接下来理一下细节</p>        <h3 id="有重合不可以包含"   >          <a href="#有重合不可以包含" class="heading-link"><i class="fas fa-link"></i></a><a href="#有重合不可以包含" class="headerlink" title="有重合不可以包含"></a>有重合不可以包含</h3>      <p>我们枚举重合长度。如果包含的话，会遍历到待接龙字符串的最后一位，所以我们不能取等。</p><ul><li><code>j</code> 从 1 开始：至少重合1个字符</li><li>不取等</li></ul><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">1</span>; j &lt; <span class="built_in">min</span>(tmp.<span class="built_in">size</span>(), s[i].<span class="built_in">size</span>()); ++j)</span><br></pre></td></tr></table></div></figure>        <h3 id="字符串是否匹配（可以重合）"   >          <a href="#字符串是否匹配（可以重合）" class="heading-link"><i class="fas fa-link"></i></a><a href="#字符串是否匹配（可以重合）" class="headerlink" title="字符串是否匹配（可以重合）"></a>字符串是否匹配（可以重合）</h3>      <p>匹配就是看当前字符的后面和待匹配字符的前面，用.substr()</p><ul><li><code>tmp.substr(tmp.size() - j)</code>：取当前龙末尾 j 个字符</li><li><code>s[i].substr(0, j)</code>：取候选单词开头 j 个字符</li><li>两者相等说明可以接龙</li></ul><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tmp.<span class="built_in">substr</span>(tmp.<span class="built_in">size</span>() - j) == s[i].<span class="built_in">substr</span>(<span class="number">0</span>, j)</span><br></pre></td></tr></table></div></figure>        <h3 id="拼接方式"   >          <a href="#拼接方式" class="heading-link"><i class="fas fa-link"></i></a><a href="#拼接方式" class="headerlink" title="拼接方式"></a>拼接方式</h3>      <ul><li>去掉重合部分：当前龙 + 单词i去掉前j个字符</li><li>比如 <code>&quot;beast&quot;</code> 接 <code>&quot;astonish&quot;</code>，重合 <code>&quot;ast&quot;</code>：<ul><li><code>&quot;beast&quot; + &quot;astonish&quot;.substr(3) = &quot;beast&quot; + &quot;onish&quot; = &quot;beastonish&quot;</code></li></ul></li></ul><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tmp + s[i].<span class="built_in">substr</span>(j)</span><br></pre></td></tr></table></div></figure>        <h3 id="次数控制"   >          <a href="#次数控制" class="heading-link"><i class="fas fa-link"></i></a><a href="#次数控制" class="headerlink" title="次数控制"></a>次数控制</h3>      <p>其实就是vis++，和一般的访问数组一样</p>        <h2 id="代码-4"   >          <a href="#代码-4" class="heading-link"><i class="fas fa-link"></i></a><a href="#代码-4" class="headerlink" title="代码"></a>代码</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line">string a[<span class="number">1000</span>];  <span class="comment">// 存储所有单词的数组</span></span><br><span class="line"><span class="type">int</span> n, ans;      <span class="comment">// n: 单词数量, ans: 记录最长龙的长度</span></span><br><span class="line"><span class="type">int</span> vis[<span class="number">1000</span>] = &#123;<span class="number">0</span>&#125;;  <span class="comment">// 记录每个单词的使用次数，初始化为0</span></span><br><span class="line">string s;        <span class="comment">// 这个变量定义后未使用，可以删除</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// DFS深度优先搜索函数</span></span><br><span class="line"><span class="comment">// tmp: 当前已经拼接形成的龙字符串</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">const</span> string&amp; tmp)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 更新最大长度：比较当前龙的长度与历史最大值</span></span><br><span class="line">    ans = <span class="built_in">max</span>(ans, <span class="built_in">int</span>(tmp.<span class="built_in">size</span>()));</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 遍历所有单词，寻找可以接龙的单词</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        <span class="comment">// 如果当前单词已经使用过2次，跳过</span></span><br><span class="line">        <span class="keyword">if</span> (vis[i] &gt;= <span class="number">2</span>) <span class="keyword">continue</span>;</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 枚举所有可能的重合长度j</span></span><br><span class="line">        <span class="comment">// j的范围：1 到 min(当前龙长度, 候选单词长度)-1</span></span><br><span class="line">        <span class="comment">// 注意：j不能等于最小值，否则会出现包含关系</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">1</span>; j &lt; <span class="built_in">min</span>(tmp.<span class="built_in">size</span>(), a[i].<span class="built_in">size</span>()); j++) &#123;</span><br><span class="line">            <span class="comment">// 检查当前龙末尾的j个字符是否等于候选单词开头的j个字符</span></span><br><span class="line">            <span class="keyword">if</span> (tmp.<span class="built_in">substr</span>(tmp.<span class="built_in">size</span>() - j) == a[i].<span class="built_in">substr</span>(<span class="number">0</span>, j)) &#123;</span><br><span class="line">                <span class="comment">// 找到可以接龙的单词，标记为已使用</span></span><br><span class="line">                vis[i]++;</span><br><span class="line">                <span class="comment">// 递归搜索：当前龙 + 候选单词去掉前j个字符（去掉重合部分）</span></span><br><span class="line">                <span class="comment">// 例如：&quot;beast&quot; + &quot;astonish&quot;.substr(3) = &quot;beast&quot; + &quot;onish&quot; = &quot;beastonish&quot;</span></span><br><span class="line">                <span class="built_in">dfs</span>(tmp + a[i].<span class="built_in">substr</span>(j));</span><br><span class="line">                <span class="comment">// 回溯：恢复该单词的使用次数，尝试其他可能性</span></span><br><span class="line">                vis[i]--;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">solve</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 读入单词数量</span></span><br><span class="line">    cin &gt;&gt; n;</span><br><span class="line">    <span class="comment">// 读入所有单词，从下标1开始存储</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        cin &gt;&gt; a[i];</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 读入起始字母</span></span><br><span class="line">    <span class="type">char</span> c;</span><br><span class="line">    cin &gt;&gt; c;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 从所有以起始字母c开头的单词开始DFS搜索</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (a[i][<span class="number">0</span>] == c) &#123;</span><br><span class="line">            vis[i]++;      <span class="comment">// 标记该起始单词使用1次</span></span><br><span class="line">            <span class="built_in">dfs</span>(a[i]);     <span class="comment">// 从该单词开始DFS搜索</span></span><br><span class="line">            vis[i]--;      <span class="comment">// 回溯：恢复使用次数</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 输出最长龙的长度</span></span><br><span class="line">    cout &lt;&lt; ans;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 加速输入输出</span></span><br><span class="line">    ios::<span class="built_in">sync_with_stdio</span>(<span class="number">0</span>), cin.<span class="built_in">tie</span>(<span class="number">0</span>), cout.<span class="built_in">tie</span>(<span class="number">0</span>);</span><br><span class="line">    <span class="built_in">solve</span>();</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h3 id="补充"   >          <a href="#补充" class="heading-link"><i class="fas fa-link"></i></a><a href="#补充" class="headerlink" title="补充"></a>补充</h3>      <p>这一版本的代码非常简单直观，但是也有它的问题</p><ul><li><strong>重复计算</strong>：相同的单词对会在不同DFS路径中反复检查重合</li><li><strong>无效尝试</strong>：有些单词根本不可能接上，但每次都要枚举</li></ul>        <h4 id="预处理重合"   >          <a href="#预处理重合" class="heading-link"><i class="fas fa-link"></i></a><a href="#预处理重合" class="headerlink" title="预处理重合"></a>预处理重合</h4>      <p>由于要长度最长，所以只需找到最小重合，重合越少最后越长。</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> overlap[N][N];  <span class="comment">// overlap[i][j]表示单词i接单词j的最小重合长度，0表示不能接</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 预处理函数</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">preprocess</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">1</span>; j &lt;= n; j++) &#123;</span><br><span class="line">            overlap[i][j] = <span class="number">0</span>;  <span class="comment">// 初始化为不能接</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> k = <span class="number">1</span>; k &lt; <span class="built_in">min</span>(s[i].<span class="built_in">size</span>(), s[j].<span class="built_in">size</span>()); k++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (s[i].<span class="built_in">substr</span>(s[i].<span class="built_in">size</span>() - k) == s[j].<span class="built_in">substr</span>(<span class="number">0</span>, k)) &#123;</span><br><span class="line">                    overlap[i][j] = k;</span><br><span class="line">                    <span class="keyword">break</span>;  <span class="comment">// 找到最小重合就退出</span></span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h4 id="预处理之后重新查表"   >          <a href="#预处理之后重新查表" class="heading-link"><i class="fas fa-link"></i></a><a href="#预处理之后重新查表" class="headerlink" title="预处理之后重新查表"></a>预处理之后重新查表</h4>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">const</span> string &amp;tmp, <span class="type">int</span> last)</span> </span>&#123;  <span class="comment">// last: 上一个单词编号</span></span><br><span class="line">    ans = <span class="built_in">max</span>(ans, (<span class="type">int</span>)tmp.<span class="built_in">size</span>());</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (vis[i] &gt;= <span class="number">2</span>) <span class="keyword">continue</span>;</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 直接查表，避免重复计算</span></span><br><span class="line">        <span class="type">int</span> k = overlap[last][i];</span><br><span class="line">        <span class="keyword">if</span> (k &gt; <span class="number">0</span>) &#123;</span><br><span class="line">            vis[i]++;</span><br><span class="line">            <span class="built_in">dfs</span>(tmp + s[i].<span class="built_in">substr</span>(k), i);</span><br><span class="line">            vis[i]--;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>完整代码</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;string&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;algorithm&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">30</span>;</span><br><span class="line"><span class="type">int</span> n, vis[N], ans;</span><br><span class="line">string s[N];</span><br><span class="line"><span class="type">char</span> c;</span><br><span class="line"><span class="type">int</span> overlap[N][N];  <span class="comment">// 预处理的重合矩阵</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">preprocess</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">1</span>; j &lt;= n; j++) &#123;</span><br><span class="line">            overlap[i][j] = <span class="number">0</span>;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> k = <span class="number">1</span>; k &lt; <span class="built_in">min</span>(s[i].<span class="built_in">size</span>(), s[j].<span class="built_in">size</span>()); k++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (s[i].<span class="built_in">substr</span>(s[i].<span class="built_in">size</span>() - k) == s[j].<span class="built_in">substr</span>(<span class="number">0</span>, k)) &#123;</span><br><span class="line">                    overlap[i][j] = k;</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">const</span> string &amp;tmp, <span class="type">int</span> last)</span> </span>&#123;</span><br><span class="line">    ans = <span class="built_in">max</span>(ans, (<span class="type">int</span>)tmp.<span class="built_in">size</span>());</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (vis[i] &gt;= <span class="number">2</span>) <span class="keyword">continue</span>;</span><br><span class="line">        <span class="keyword">if</span> (overlap[last][i] &gt; <span class="number">0</span>) &#123;</span><br><span class="line">            vis[i]++;</span><br><span class="line">            <span class="built_in">dfs</span>(tmp + s[i].<span class="built_in">substr</span>(overlap[last][i]), i);</span><br><span class="line">            vis[i]--;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    cin.<span class="built_in">tie</span>(<span class="literal">nullptr</span>);</span><br><span class="line">    ios::<span class="built_in">sync_with_stdio</span>(<span class="literal">false</span>);</span><br><span class="line">    </span><br><span class="line">    cin &gt;&gt; n;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) cin &gt;&gt; s[i];</span><br><span class="line">    cin &gt;&gt; c;</span><br><span class="line">    </span><br><span class="line">    <span class="built_in">preprocess</span>();  <span class="comment">// 关键：预处理</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (s[i][<span class="number">0</span>] == c) &#123;</span><br><span class="line">            vis[i]++;</span><br><span class="line">            <span class="built_in">dfs</span>(s[i], i);</span><br><span class="line">            vis[i]--;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    cout &lt;&lt; ans &lt;&lt; <span class="string">&#x27;\n&#x27;</span>;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="Scales-S"   >          <a href="#Scales-S" class="heading-link"><i class="fas fa-link"></i></a><a href="#Scales-S" class="headerlink" title="Scales S"></a>Scales S</h1>      <p><span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/P5194" >P5194 [USACO05DEC] Scales S</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>        <h2 id="题意-9"   >          <a href="#题意-9" class="heading-link"><i class="fas fa-link"></i></a><a href="#题意-9" class="headerlink" title="题意"></a>题意</h2>      <p>有一个单调不降的序列，给你一个上限，你需要在序列里选出数，让它们累加之后最接近（但是不超过）给定的上限。</p>        <h2 id="思路-9"   >          <a href="#思路-9" class="heading-link"><i class="fas fa-link"></i></a><a href="#思路-9" class="headerlink" title="思路"></a>思路</h2>      <p> 直接暴力搜索其实很简单，每个砝码选或者不选。不选就下一个，选的话加上这个质量。然后一直递归。考虑完所有砝码后检查是否合法并更新答案。</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;algorithm&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ll long long</span></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> MAX_N = <span class="number">1005</span>;</span><br><span class="line">ll m[MAX_N];    <span class="comment">// 存储每个砝码的质量</span></span><br><span class="line">ll sum;         <span class="comment">// 能称出的最大质量</span></span><br><span class="line">ll n, c;       <span class="comment">// 砝码数量, 天平最大承重</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> index, ll cur)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 如果已经考虑完所有砝码，更新答案并返回</span></span><br><span class="line">    <span class="keyword">if</span> (index &gt; n) &#123;</span><br><span class="line">        <span class="keyword">if</span> (cur &lt;= c) &#123;</span><br><span class="line">            sum = <span class="built_in">max</span>(sum, cur);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 剪枝：如果当前已超重，直接返回</span></span><br><span class="line">    <span class="keyword">if</span> (cur &gt; c) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 选择1: 选择当前砝码</span></span><br><span class="line">    <span class="built_in">dfs</span>(index + <span class="number">1</span>, cur + m[index]);</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 选择2: 不选当前砝码</span></span><br><span class="line">    <span class="built_in">dfs</span>(index + <span class="number">1</span>, cur);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 输入数据</span></span><br><span class="line">    cin &gt;&gt; n &gt;&gt; c;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        cin &gt;&gt; m[i];</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 初始化最大质量为0</span></span><br><span class="line">    sum = <span class="number">0</span>;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 开始DFS搜索：从第一个砝码开始考虑，当前总质量为0</span></span><br><span class="line">    <span class="built_in">dfs</span>(<span class="number">1</span>, <span class="number">0</span>);</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 输出结果</span></span><br><span class="line">    cout &lt;&lt; sum &lt;&lt; endl;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>如果你这么写了，喜提TLE。</p><p><strong>如果用dfs想优化时间复杂度，我们通常会进行剪枝</strong>，显然我们已经剪枝过了。那没有办法优化了吗？还能怎样进行剪枝？</p><p>注意到题目给出，它给出的序列是单调不降的。那我们可以从最后也就是最大数开始遍历。就可以借助<strong>前缀和</strong>能帮快速判断能否全取。总结一下</p><ol><li><strong>从后往前考虑</strong>：从最后一个砝码开始（index &#x3D; n）</li><li><strong>两个选择</strong>：<ul><li>选当前砝码：<code>dfs(index-1, cur + m[index])</code></li><li>不选当前砝码：<code>dfs(index-1, cur)</code></li></ul></li><li><strong>两个剪枝</strong>：<ul><li>超重剪枝：当前总质量 &gt; 承重</li><li>全取剪枝：当前质量 + 剩余所有砝码 ≤ 承重</li></ul></li></ol>        <h2 id="代码-5"   >          <a href="#代码-5" class="heading-link"><i class="fas fa-link"></i></a><a href="#代码-5" class="headerlink" title="代码"></a>代码</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ll long long</span></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> MAX_N = <span class="number">1005</span>;</span><br><span class="line">ll m[MAX_N];    <span class="comment">// 存储每个砝码的质量</span></span><br><span class="line">ll maxSum;      <span class="comment">// 能称出的最大质量</span></span><br><span class="line">ll pre[MAX_N];  <span class="comment">// 前缀和数组</span></span><br><span class="line">ll n, c;        <span class="comment">// 砝码数量, 天平最大承重</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> index, ll cur)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 更新最大质量</span></span><br><span class="line">    maxSum = <span class="built_in">max</span>(maxSum, cur);</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 考虑完所有砝码返回</span></span><br><span class="line">    <span class="keyword">if</span> (index == <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 剪枝1: 如果当前总质量已经超过天平承重，直接返回</span></span><br><span class="line">    <span class="keyword">if</span>(cur &gt; c)&#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 剪枝2: 如果当前总质量加上剩余所有砝码质量仍然不超过承重，则直接全取</span></span><br><span class="line">    <span class="keyword">if</span>(cur + pre[index] &lt;= c)&#123;</span><br><span class="line">        maxSum = <span class="built_in">max</span>(maxSum, cur + pre[index]);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 选择当前砝码（如果加上后不超重）</span></span><br><span class="line">    <span class="keyword">if</span>(cur + m[index] &lt;= c)&#123;</span><br><span class="line">        <span class="built_in">dfs</span>(index - <span class="number">1</span>, cur + m[index]);</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 不选当前砝码</span></span><br><span class="line">    <span class="built_in">dfs</span>(index - <span class="number">1</span>, cur);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 输入数据</span></span><br><span class="line">    cin &gt;&gt; n &gt;&gt; c;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        cin &gt;&gt; m[i];</span><br><span class="line">        pre[i] = pre[i - <span class="number">1</span>] + m[i];</span><br><span class="line">    &#125;   </span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 初始化最大质量为0</span></span><br><span class="line">    maxSum = <span class="number">0</span>;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 开始DFS搜索：从最后一个砝码开始考虑，当前总质量为0</span></span><br><span class="line">    <span class="built_in">dfs</span>(n, <span class="number">0</span>);</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 输出结果</span></span><br><span class="line">    cout &lt;&lt; maxSum &lt;&lt; endl;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="XR-2-奇迹"   >          <a href="#XR-2-奇迹" class="heading-link"><i class="fas fa-link"></i></a><a href="#XR-2-奇迹" class="headerlink" title="[XR-2]奇迹"></a>[XR-2]奇迹</h1>      <p><span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/P5440" >洛谷P5440</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>        <h2 id="题意-10"   >          <a href="#题意-10" class="heading-link"><i class="fas fa-link"></i></a><a href="#题意-10" class="headerlink" title="题意"></a>题意</h2>      <p>给你一个八位数，这八位数中会有不确定的数字用‘-’表示，第 1∼4 位构成年，第 5∼6 位构成月，第 7∼8 位构成日，不足位数用 0 补足，同时，要求日期所代表的这一天真实存在，且年的范围为 1∼9999。要求由“日”组成的两位数，由“月+日”组成的四位数，由“年+月+日”组成的八位数均为<strong>质数</strong>。</p>        <h2 id="思路-10"   >          <a href="#思路-10" class="heading-link"><i class="fas fa-link"></i></a><a href="#思路-10" class="headerlink" title="思路"></a>思路</h2>      <p>既然是dfs专题，那我们首先想到的就是dfs暴力填充。填充完后判断这个日期是不是一个合法日期。比如肯定不能出现13月或者2月30这种。当然闰年也得注意一下。又因为和质数有关，所以我们需要一个质数判断函数（这里用一下欧拉筛优化）。思路好像很清晰了。那怎么设置这个dfs呢。</p><p>要传给dfs的参数是什么，毫无疑问是已经确定好的数字位数d。当d&#x3D;&#x3D;8时我们判断是否符合题意。当d!&#x3D;8时，我们就要判断当前位是不是一个固定的数字。如果是的话直接过，dfs(n+1)，如果不是的话对当前位尝试0-9依次填充。（记得回溯）</p><p>欧拉筛板子，没什么好说的</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">Euler_prime</span><span class="params">()</span> </span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    vis[<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line">    vis[<span class="number">1</span>] = <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">2</span>; i &lt;= N; i++)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span>(!vis[i]) prime[x++] = i;</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> j = <span class="number">0</span>; j &lt; x; j++)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">if</span>(i * prime[j] &gt; N) <span class="keyword">break</span>;</span><br><span class="line">            vis[i * prime[j]] = <span class="number">1</span>;</span><br><span class="line">            <span class="keyword">if</span>(i % prime[j] == <span class="number">0</span>) <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>判断闰年，也很基础</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">bool</span> <span class="title">is_run</span><span class="params">(<span class="type">int</span> y)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(y % <span class="number">4</span> == <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">if</span>(y % <span class="number">100</span> == <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span>(y % <span class="number">400</span> == <span class="number">0</span>) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>检查日期合法性,分成年月日分别判断合法性</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">bool</span> <span class="title">legal</span><span class="params">(<span class="type">int</span> y, <span class="type">int</span> m, <span class="type">int</span> d)</span> </span>&#123;</span><br><span class="line">    <span class="comment">//月份不能超过12，年月日不可为0</span></span><br><span class="line">    <span class="keyword">if</span>(m &gt; <span class="number">12</span> || m == <span class="number">0</span> || d == <span class="number">0</span> || y == <span class="number">0</span>) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    <span class="comment">//闰年特判</span></span><br><span class="line">    <span class="keyword">if</span>(m == <span class="number">2</span>) &#123;</span><br><span class="line">        <span class="keyword">if</span>(<span class="built_in">is_run</span>(y)) &#123;</span><br><span class="line">            <span class="keyword">if</span>(d &gt; <span class="number">29</span>) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">if</span>(d &gt; <span class="number">28</span>) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125; </span><br><span class="line">    <span class="comment">//判断日期在那个月是否存在</span></span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="type">const</span> <span class="type">int</span> daynum[] = &#123;<span class="number">0</span>,<span class="number">31</span>,<span class="number">28</span>,<span class="number">31</span>,<span class="number">30</span>,<span class="number">31</span>,<span class="number">30</span>,<span class="number">31</span>,<span class="number">31</span>,<span class="number">30</span>,<span class="number">31</span>,<span class="number">30</span>,<span class="number">31</span>&#125;;<span class="comment">//提前预处理，关于月份和日期的一个常用小技巧</span></span><br><span class="line">        <span class="keyword">if</span>(d &gt; daynum[m]) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>还有一个比较关键的部分是，你如何存储这个输入，可以让你的遍历更新更方便。因为带特殊符号，所以我们最开始输入一定是字符串。又因为涉及到整数运算，所以我们还要标记一下可以替换的数位。我们用一个数组date来标记，如果date&#x3D;&#x3D;-1，表示可以替换。不然的话date&#x3D;s[i]-‘0’转换为数字。</p>        <h3 id="dfs构建"   >          <a href="#dfs构建" class="heading-link"><i class="fas fa-link"></i></a><a href="#dfs构建" class="headerlink" title="dfs构建"></a>dfs构建</h3>      <p>关键的构建dfs，我们采用按位构建的方法。我们定义dfs(d)表示当前正在处理第d位（从0开始计数）。当d&#x3D;&#x3D;8时，说明我们已经构建了一个完整的8位数，此时进行日期合法性和质数条件的检查。</p><p>在dfs过程中，我们维护一个全局变量num，表示当前构建的数字。对于每一位：</p><ul><li>如果该位是确定的（date[d] !&#x3D; -1），我们直接将这个数字加到num中，然后递归处理下一位</li><li>如果该位是不确定的（date[d] &#x3D;&#x3D; -1），我们就需要尝试0-9的所有可能</li></ul><p>但是直接尝试0-9的所有组合会导致搜索空间很大，所以我们需要进行剪枝优化：</p><ol><li><strong>月份第一位剪枝</strong>（d&#x3D;&#x3D;4）：月份的第一位只能是0或1，因为月份最大是12，所以当i&#x3D;&#x3D;2时可以直接break，因为20几月不存在</li><li><strong>月份有效性剪枝</strong>（d&#x3D;&#x3D;5）：当处理月份的第二位时：<ul><li>如果月份第一位是0（date[4]&#x3D;&#x3D;0），那么第二位不能是0，因为00月不存在</li><li>如果当前尝试的月份超过12，可以直接break</li></ul></li><li><strong>日期第一位剪枝</strong>（d&#x3D;&#x3D;6）：日期的第一位最大只能是3，因为日期最大是31，所以当i&#x3D;&#x3D;4时可以直接break</li></ol><p>这些剪枝能显著减少搜索空间，让算法在合理时间内完成。</p><p>当构建完8位数后，我们将其分解为年、月、日三部分：</p><ul><li>年 &#x3D; num &#x2F; 10000</li><li>月 &#x3D; (num % 10000) &#x2F; 100</li><li>日 &#x3D; num % 100</li></ul><p>然后检查：</p><ol><li>日期是否合法（年份1-9999，月份1-12，日期符合当月天数）</li><li>日、月日、年月日三个数是否都是质数</li></ol><p>如果都满足，就找到一个有效解，ans加1。</p>        <h2 id="代码-6"   >          <a href="#代码-6" class="heading-link"><i class="fas fa-link"></i></a><a href="#代码-6" class="headerlink" title="代码"></a>代码</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ll long long</span></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">100000000</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> vis[N + <span class="number">10</span>];    </span><br><span class="line"><span class="type">int</span> prime[N + <span class="number">10</span>];</span><br><span class="line"><span class="type">int</span> x = <span class="number">0</span>;</span><br><span class="line"><span class="type">int</span> ans = <span class="number">0</span>;</span><br><span class="line"><span class="type">int</span> date[<span class="number">10</span>];  </span><br><span class="line"><span class="type">int</span> num = <span class="number">0</span>;   </span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">Euler_prime</span><span class="params">()</span> </span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    vis[<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line">    vis[<span class="number">1</span>] = <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">2</span>; i &lt;= N; i++)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span>(!vis[i]) prime[x++] = i;</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> j = <span class="number">0</span>; j &lt; x; j++)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">if</span>(i * prime[j] &gt; N) <span class="keyword">break</span>;</span><br><span class="line">            vis[i * prime[j]] = <span class="number">1</span>;</span><br><span class="line">            <span class="keyword">if</span>(i % prime[j] == <span class="number">0</span>) <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">bool</span> <span class="title">is_run</span><span class="params">(<span class="type">int</span> y)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(y % <span class="number">4</span> == <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">if</span>(y % <span class="number">100</span> == <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span>(y % <span class="number">400</span> == <span class="number">0</span>) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">bool</span> <span class="title">legal</span><span class="params">(<span class="type">int</span> y, <span class="type">int</span> m, <span class="type">int</span> d)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(m &gt; <span class="number">12</span> || m == <span class="number">0</span> || d == <span class="number">0</span> || y == <span class="number">0</span>) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    <span class="keyword">if</span>(m == <span class="number">2</span>) &#123;</span><br><span class="line">        <span class="keyword">if</span>(<span class="built_in">is_run</span>(y)) &#123;</span><br><span class="line">            <span class="keyword">if</span>(d &gt; <span class="number">29</span>) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">if</span>(d &gt; <span class="number">28</span>) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="type">const</span> <span class="type">int</span> daynum[] = &#123;<span class="number">0</span>,<span class="number">31</span>,<span class="number">28</span>,<span class="number">31</span>,<span class="number">30</span>,<span class="number">31</span>,<span class="number">30</span>,<span class="number">31</span>,<span class="number">31</span>,<span class="number">30</span>,<span class="number">31</span>,<span class="number">30</span>,<span class="number">31</span>&#125;;</span><br><span class="line">        <span class="keyword">if</span>(d &gt; daynum[m]) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> d)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(d == <span class="number">8</span>) &#123;</span><br><span class="line">        <span class="type">int</span> y = num / <span class="number">10000</span>;</span><br><span class="line">        <span class="type">int</span> m = (num % <span class="number">10000</span>) / <span class="number">100</span>;</span><br><span class="line">        <span class="type">int</span> day = num % <span class="number">100</span>;  </span><br><span class="line">        </span><br><span class="line">        <span class="keyword">if</span>(<span class="built_in">legal</span>(y, m, day)) &#123;</span><br><span class="line">            <span class="keyword">if</span>(!vis[day] &amp;&amp; !vis[m * <span class="number">100</span> + day] &amp;&amp; !vis[y * <span class="number">10000</span> + m * <span class="number">100</span> + day]) &#123;</span><br><span class="line">                ans++;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span>(date[d] != <span class="number">-1</span>) &#123;</span><br><span class="line">        num = num * <span class="number">10</span> + date[d];</span><br><span class="line">        <span class="built_in">dfs</span>(d + <span class="number">1</span>);</span><br><span class="line">        num /= <span class="number">10</span>;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i &lt;= <span class="number">9</span>; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span>(d == <span class="number">4</span> &amp;&amp; i == <span class="number">2</span>) <span class="keyword">break</span>; </span><br><span class="line">        <span class="keyword">if</span>(d == <span class="number">5</span> &amp;&amp; i == <span class="number">0</span> &amp;&amp; date[<span class="number">4</span>] == <span class="number">0</span>) <span class="keyword">continue</span>;  </span><br><span class="line">        <span class="keyword">if</span>(d == <span class="number">5</span> &amp;&amp; date[<span class="number">4</span>] * <span class="number">10</span> + i &gt; <span class="number">12</span>) <span class="keyword">break</span>; </span><br><span class="line">        <span class="keyword">if</span>(d == <span class="number">6</span> &amp;&amp; i == <span class="number">4</span>) <span class="keyword">break</span>;  </span><br><span class="line">        </span><br><span class="line">        date[d] = i;</span><br><span class="line">        num = num * <span class="number">10</span> + i;</span><br><span class="line">        <span class="built_in">dfs</span>(d + <span class="number">1</span>);</span><br><span class="line">        date[d] = <span class="number">-1</span>;</span><br><span class="line">        num /= <span class="number">10</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    ios::<span class="built_in">sync_with_stdio</span>(<span class="literal">false</span>);</span><br><span class="line">    cin.<span class="built_in">tie</span>(<span class="number">0</span>);</span><br><span class="line">    <span class="type">int</span> t;</span><br><span class="line">    cin &gt;&gt; t;</span><br><span class="line">    <span class="built_in">Euler_prime</span>();</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">while</span>(t--) &#123;</span><br><span class="line">        ans = <span class="number">0</span>;</span><br><span class="line">        num = <span class="number">0</span>;</span><br><span class="line">        string s;</span><br><span class="line">        cin &gt;&gt; s;</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i &lt; <span class="number">8</span>; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span>(s[i] == <span class="string">&#x27;-&#x27;</span>) &#123;</span><br><span class="line">                date[i] = <span class="number">-1</span>;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                date[i] = s[i] - <span class="string">&#x27;0&#x27;</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        <span class="built_in">dfs</span>(<span class="number">0</span>);</span><br><span class="line">        cout &lt;&lt; ans &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="出题人题解"   >          <a href="#出题人题解" class="heading-link"><i class="fas fa-link"></i></a><a href="#出题人题解" class="headerlink" title="出题人题解"></a>出题人题解</h2>      <p>看到题解的那一刻我是有点破防的。我对我写出的逻辑清晰的代码十分满意，但洋洋洒洒也有一百行以上了。题解是把预处理做到了极致。</p><p>采用<strong>预处理+模式匹配</strong>的解法，核心思想是：</p><ol><li><strong>预先计算所有可能的奇迹日期</strong></li><li><strong>对每个查询，检查预处理日期是否匹配输入模式</strong></li></ol><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 可能的质数日和每月天数</span></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> prime_days[] = &#123;<span class="number">0</span>, <span class="number">3</span>, <span class="number">5</span>, <span class="number">7</span>, <span class="number">11</span>, <span class="number">13</span>, <span class="number">17</span>, <span class="number">19</span>, <span class="number">23</span>, <span class="number">29</span>, <span class="number">31</span>&#125;;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> month_days[] = &#123;<span class="number">0</span>, <span class="number">31</span>, <span class="number">28</span>, <span class="number">31</span>, <span class="number">30</span>, <span class="number">31</span>, <span class="number">30</span>, <span class="number">31</span>, <span class="number">31</span>, <span class="number">30</span>, <span class="number">31</span>, <span class="number">30</span>, <span class="number">31</span>&#125;;</span><br><span class="line"></span><br><span class="line">vector&lt;<span class="type">int</span>&gt; valid_dates; <span class="comment">// 存储所有奇迹日期</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 判断质数</span></span><br><span class="line"><span class="function"><span class="type">bool</span> <span class="title">is_prime</span><span class="params">(<span class="type">int</span> x)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (x &lt; <span class="number">2</span>) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">2</span>; i * i &lt;= x; i++)</span><br><span class="line">        <span class="keyword">if</span> (x % i == <span class="number">0</span>) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 判断闰年</span></span><br><span class="line"><span class="function"><span class="type">bool</span> <span class="title">is_leap_year</span><span class="params">(<span class="type">int</span> year)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> (year % <span class="number">4</span> == <span class="number">0</span> &amp;&amp; year % <span class="number">100</span> != <span class="number">0</span>) || (year % <span class="number">400</span> == <span class="number">0</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 预处理所有奇迹日期</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">preprocess</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 处理普通日期</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> month = <span class="number">1</span>; month &lt;= <span class="number">12</span>; month++) &#123;</span><br><span class="line">        <span class="type">int</span> max_day = month_days[month];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">1</span>; j &lt;= <span class="number">10</span>; j++) &#123;</span><br><span class="line">            <span class="type">int</span> day = prime_days[j];</span><br><span class="line">            <span class="keyword">if</span> (day &gt; max_day) <span class="keyword">continue</span>;</span><br><span class="line">            <span class="comment">// 检查月日是否为质数</span></span><br><span class="line">            <span class="type">int</span> month_day = month * <span class="number">100</span> + day;</span><br><span class="line">            <span class="keyword">if</span> (!<span class="built_in">is_prime</span>(month_day)) <span class="keyword">continue</span>;</span><br><span class="line">            <span class="comment">// 检查日是否为质数</span></span><br><span class="line">            <span class="keyword">if</span> (!<span class="built_in">is_prime</span>(day)) <span class="keyword">continue</span>;</span><br><span class="line">            <span class="comment">// 组合年份检查完整日期</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> year = <span class="number">1</span>; year &lt;= <span class="number">9999</span>; year++) &#123;</span><br><span class="line">                <span class="comment">// 特殊处理2月29日</span></span><br><span class="line">                <span class="keyword">if</span> (month == <span class="number">2</span> &amp;&amp; day == <span class="number">29</span> &amp;&amp; !<span class="built_in">is_leap_year</span>(year)) <span class="keyword">continue</span>;</span><br><span class="line">                <span class="type">int</span> full_date = year * <span class="number">10000</span> + month_day;</span><br><span class="line">                <span class="keyword">if</span> (<span class="built_in">is_prime</span>(full_date)) &#123;</span><br><span class="line">                    valid_dates.<span class="built_in">push_back</span>(full_date);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    ios::<span class="built_in">sync_with_stdio</span>(<span class="literal">false</span>);</span><br><span class="line">    cin.<span class="built_in">tie</span>(<span class="number">0</span>);</span><br><span class="line">    </span><br><span class="line">    <span class="built_in">preprocess</span>(); <span class="comment">// 预处理</span></span><br><span class="line">    </span><br><span class="line">    <span class="type">int</span> T;</span><br><span class="line">    cin &gt;&gt; T;</span><br><span class="line">    <span class="keyword">while</span> (T--) &#123;</span><br><span class="line">        string pattern;</span><br><span class="line">        cin &gt;&gt; pattern;</span><br><span class="line">        </span><br><span class="line">        <span class="type">int</span> count = <span class="number">0</span>;</span><br><span class="line">        <span class="comment">// 检查每个预处理日期是否匹配模式</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> date : valid_dates) &#123;</span><br><span class="line">            string date_str = <span class="built_in">to_string</span>(date);</span><br><span class="line">            <span class="comment">// 补前导0到8位</span></span><br><span class="line">            <span class="keyword">while</span> (date_str.<span class="built_in">length</span>() &lt; <span class="number">8</span>) &#123;</span><br><span class="line">                date_str = <span class="string">&quot;0&quot;</span> + date_str;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="type">bool</span> match = <span class="literal">true</span>;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; <span class="number">8</span>; i++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (pattern[i] != <span class="string">&#x27;-&#x27;</span> &amp;&amp; pattern[i] != date_str[i]) &#123;</span><br><span class="line">                    match = <span class="literal">false</span>;</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (match) count++;</span><br><span class="line">        &#125;</span><br><span class="line">        cout &lt;&lt; count &lt;&lt; <span class="string">&quot;\n&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="油滴扩展"   >          <a href="#油滴扩展" class="heading-link"><i class="fas fa-link"></i></a><a href="#油滴扩展" class="headerlink" title="油滴扩展"></a>油滴扩展</h1>      <p><span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/P1378" >P1378 油滴扩展 - 洛谷</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>        <h2 id="题意-11"   >          <a href="#题意-11" class="heading-link"><i class="fas fa-link"></i></a><a href="#题意-11" class="headerlink" title="题意"></a>题意</h2>      <p>在一个矩形框内给定 N 个点，我们可以按一定顺序在这些点上放置油滴。<br>油滴会扩展成圆形，直到碰到矩形边界或其它已放置的油滴。<br>目标是<strong>安排放置顺序</strong>，使所有油滴覆盖的总面积最大，从而矩形剩余面积最小。</p>        <h2 id="思路-11"   >          <a href="#思路-11" class="heading-link"><i class="fas fa-link"></i></a><a href="#思路-11" class="headerlink" title="思路"></a>思路</h2>      <p>人为什么能蠢成这样，半径应该是<strong>连续值</strong>，由几何条件决定，不是离散枚举。就这样写出了一段史山(划掉)</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">mark</span><span class="params">(point p,<span class="type">int</span> r)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = p.x - r; i &lt;= p.x + r; i++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> j = p.y - r; j &lt;= p.y + r; j++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (i &gt;= <span class="number">0</span> &amp;&amp; i &lt; n &amp;&amp; j &gt;= <span class="number">0</span> &amp;&amp; j &lt; n) &#123;</span><br><span class="line">                <span class="keyword">if</span> ((i - p.x) * (i - p.x) + (j - p.y) * (j - p.y) &lt;= r * r) &#123;</span><br><span class="line">                    a[i][j] = <span class="number">1</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></div></figure><p>言归正传。</p><ul><li><p>对于当前要放置的油滴，它的最大半径由两个因素决定：</p><ol><li>到矩形四边的距离</li><li>到已放置油滴的圆心距离减去该油滴的半径</li></ol></li><li><p>半径公式：</p><p>text</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">r = min( dist_to_boundary, dist_to_other_circle_radius )</span><br></pre></td></tr></table></div></figure><p>其中 <code>dist_to_other_circle_radius</code> 对于每个已放置油滴 j 是 <code>dist(i, j) - r_j</code>，如果小于 0 则半径取 0。</p></li><li><p>用 DFS 枚举所有排列顺序，计算每种顺序下的油滴总面积，取最大值。</p></li></ul><hr>        <h3 id="DFS-框架"   >          <a href="#DFS-框架" class="heading-link"><i class="fas fa-link"></i></a><a href="#DFS-框架" class="headerlink" title="DFS 框架"></a>DFS 框架</h3>      <ul><li><strong>状态</strong>：当前已放置的油滴数量 <code>cnt</code>，当前油滴总面积 <code>total_area</code></li><li><strong>选择</strong>：所有未使用的油滴</li><li><strong>递归深度</strong>：油滴数量 N</li><li><strong>回溯</strong>：恢复油滴的使用状态和半径</li></ul><hr>        <h3 id="关键细节"   >          <a href="#关键细节" class="heading-link"><i class="fas fa-link"></i></a><a href="#关键细节" class="headerlink" title="关键细节"></a>关键细节</h3>      <ol><li><strong>矩形边界处理</strong><br>输入的两个顶点不一定是左下和右上，需要先交换确保 <code>x1 ≤ x2, y1 ≤ y2</code>。</li><li><strong>半径计算</strong><br>半径是连续值，由几何条件决定，不是离散枚举。</li><li><strong>四舍五入输出</strong><br>最终结果用 <code>round()</code> 处理。</li></ol>        <h2 id="代码-7"   >          <a href="#代码-7" class="heading-link"><i class="fas fa-link"></i></a><a href="#代码-7" class="headerlink" title="代码"></a>代码</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">const</span> <span class="type">double</span> PI = <span class="built_in">acos</span>(<span class="number">-1.0</span>);</span><br><span class="line"><span class="type">int</span> n;</span><br><span class="line"><span class="type">double</span> x, y, x2, y2;</span><br><span class="line"><span class="type">double</span> max_oil = <span class="number">0</span>;</span><br><span class="line"><span class="type">bool</span> vis[<span class="number">10</span>];</span><br><span class="line"><span class="type">double</span> r[<span class="number">10</span>]; </span><br><span class="line">vector&lt;pair&lt;<span class="type">double</span>, <span class="type">double</span>&gt;&gt; points;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 两点距离</span></span><br><span class="line"><span class="function"><span class="type">double</span> <span class="title">dist</span><span class="params">(<span class="type">double</span> x, <span class="type">double</span> y, <span class="type">double</span> x2, <span class="type">double</span> y2)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">sqrt</span>((x - x2) * (x - x2) + (y - y2) * (y - y2));</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> cnt, <span class="type">double</span> total_area)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (cnt == n) &#123;</span><br><span class="line">        max_oil = <span class="built_in">max</span>(max_oil, total_area);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!vis[i]) &#123;</span><br><span class="line">            <span class="comment">// 计算油滴 i 的最大半径</span></span><br><span class="line">            <span class="type">double</span> max_r = <span class="number">1e9</span>;</span><br><span class="line">            <span class="comment">// 到矩形四边的距离</span></span><br><span class="line">            max_r = <span class="built_in">min</span>(max_r, <span class="built_in">abs</span>(points[i].first - x));</span><br><span class="line">            max_r = <span class="built_in">min</span>(max_r, <span class="built_in">abs</span>(points[i].first - x2));</span><br><span class="line">            max_r = <span class="built_in">min</span>(max_r, <span class="built_in">abs</span>(points[i].second - y));</span><br><span class="line">            max_r = <span class="built_in">min</span>(max_r, <span class="built_in">abs</span>(points[i].second - y2));</span><br><span class="line">            <span class="comment">// 到已放置油滴的距离</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">0</span>; j &lt; n; j++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (vis[j]) &#123;</span><br><span class="line">                    <span class="type">double</span> d = <span class="built_in">dist</span>(points[i].first, points[i].second, points[j].first, points[j].second);</span><br><span class="line">                    max_r = <span class="built_in">min</span>(max_r, d - r[j]);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">// 如果 max_r &lt; 0，说明这个点在其他油滴内部，半径取 0</span></span><br><span class="line">            <span class="keyword">if</span> (max_r &lt; <span class="number">0</span>) max_r = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">            vis[i] = <span class="literal">true</span>;</span><br><span class="line">            r[i] = max_r;</span><br><span class="line">            <span class="built_in">dfs</span>(cnt + <span class="number">1</span>, total_area + PI * r[i] * r[i]);</span><br><span class="line">            vis[i] = <span class="literal">false</span>;</span><br><span class="line">            r[i] = <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    cin &gt;&gt; n;</span><br><span class="line">    cin &gt;&gt; x &gt;&gt; y &gt;&gt; x2 &gt;&gt; y2;</span><br><span class="line">    points.<span class="built_in">resize</span>(n);</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">        cin &gt;&gt; points[i].first &gt;&gt; points[i].second;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (x &gt; x2) <span class="built_in">swap</span>(x, x2);</span><br><span class="line">    <span class="keyword">if</span> (y &gt; y2) <span class="built_in">swap</span>(y, y2);</span><br><span class="line"></span><br><span class="line">    <span class="type">double</span> rect_area = (x2 - x) * (y2 - y);</span><br><span class="line">    <span class="built_in">dfs</span>(<span class="number">0</span>, <span class="number">0.0</span>);</span><br><span class="line"></span><br><span class="line">    <span class="type">int</span> ans = <span class="built_in">round</span>(rect_area - max_oil);</span><br><span class="line">    cout &lt;&lt; ans &lt;&lt; endl;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="取数游戏"   >          <a href="#取数游戏" class="heading-link"><i class="fas fa-link"></i></a><a href="#取数游戏" class="headerlink" title="取数游戏"></a>取数游戏</h1>      <p><span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/P1123" >P1123 取数游戏 - 洛谷</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>        <h2 id="题意-12"   >          <a href="#题意-12" class="heading-link"><i class="fas fa-link"></i></a><a href="#题意-12" class="headerlink" title="题意"></a>题意</h2>      <p>一个n*m的数组里面取数字，要求互不相邻（周围八个），求最多能取出几个。</p>        <h2 id="思路-12"   >          <a href="#思路-12" class="heading-link"><i class="fas fa-link"></i></a><a href="#思路-12" class="headerlink" title="思路"></a>思路</h2>      <p>这种二维的数组，我们是不方便遍历回溯的，因为我们需要变量稳定，一个不受另一个影响。所以就会用到一个常用的技巧，二维转一维。事实上我们只要规定从上往下从左到右开始数，知道是第几个就可以知道它的二维坐标。</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> x = (pos<span class="number">-1</span>) / m + <span class="number">1</span>;  </span><br><span class="line"><span class="type">int</span> y = (pos<span class="number">-1</span>) % m + <span class="number">1</span>;</span><br></pre></td></tr></table></div></figure><p>原理不细说，可以自己想想。那么我们dfs的构造就明细了。</p><ul><li><strong>状态</strong> 枚举到了第pos个数字，选了sum个数</li><li><strong>选择</strong> 对于这个数你可以选或不选</li></ul><p>当然还有一个约束条件是不能相邻，那在外面写一个判断函数就好。</p>        <h2 id="代码-8"   >          <a href="#代码-8" class="heading-link"><i class="fas fa-link"></i></a><a href="#代码-8" class="headerlink" title="代码"></a>代码</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">int</span> n,m;</span><br><span class="line"><span class="type">int</span> dx[]=&#123;<span class="number">-1</span>,<span class="number">-1</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">-1</span>&#125;;</span><br><span class="line"><span class="type">int</span> dy[]=&#123;<span class="number">0</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">-1</span>,<span class="number">-1</span>,<span class="number">-1</span>&#125;;</span><br><span class="line"><span class="type">int</span> a[<span class="number">7</span>][<span class="number">7</span>];</span><br><span class="line"><span class="type">bool</span> vis[<span class="number">7</span>][<span class="number">7</span>];</span><br><span class="line"><span class="type">int</span> max1;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">bool</span> <span class="title">check</span><span class="params">(<span class="type">int</span> x,<span class="type">int</span> y)</span></span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">0</span>;i&lt;<span class="number">8</span>;i++)&#123;</span><br><span class="line">        <span class="type">int</span> nx=x+dx[i];</span><br><span class="line">        <span class="type">int</span> ny=y+dy[i];</span><br><span class="line">        <span class="keyword">if</span>(nx&gt;=<span class="number">1</span> &amp;&amp; nx&lt;=n &amp;&amp; ny&gt;=<span class="number">1</span> &amp;&amp; ny&lt;=m &amp;&amp; vis[nx][ny])&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> pos,<span class="type">int</span> sum)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(pos&gt;n*m)&#123;</span><br><span class="line">        max1=<span class="built_in">max</span>(max1,sum);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="type">int</span> x = (pos<span class="number">-1</span>) / m + <span class="number">1</span>;  </span><br><span class="line">    <span class="type">int</span> y = (pos<span class="number">-1</span>) % m + <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 不选当前位置</span></span><br><span class="line">    <span class="built_in">dfs</span>(pos<span class="number">+1</span>,sum);</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 选当前位置（如果允许）</span></span><br><span class="line">    <span class="keyword">if</span>(<span class="built_in">check</span>(x,y))&#123;</span><br><span class="line">        vis[x][y]=<span class="literal">true</span>;</span><br><span class="line">        <span class="built_in">dfs</span>(pos<span class="number">+1</span>,sum+a[x][y]);</span><br><span class="line">        vis[x][y]=<span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    ios_base::<span class="built_in">sync_with_stdio</span>(<span class="literal">false</span>);</span><br><span class="line">    cin.<span class="built_in">tie</span>(<span class="literal">NULL</span>);</span><br><span class="line">    cout.<span class="built_in">tie</span>(<span class="literal">NULL</span>);</span><br><span class="line">    <span class="type">int</span> t;</span><br><span class="line">    cin &gt;&gt; t;</span><br><span class="line">    <span class="keyword">while</span> (t--) &#123;</span><br><span class="line">        cin &gt;&gt; n &gt;&gt; m;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">1</span>; j &lt;= m; j++) &#123;</span><br><span class="line">                cin &gt;&gt; a[i][j];</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        max1 = <span class="number">0</span>;  <span class="comment">// 每次测试用例都要重置</span></span><br><span class="line">        <span class="built_in">memset</span>(vis, <span class="literal">false</span>, <span class="built_in">sizeof</span>(vis));  <span class="comment">// 重置访问数组</span></span><br><span class="line">        <span class="built_in">dfs</span>(<span class="number">1</span>,<span class="number">0</span>);</span><br><span class="line">        cout &lt;&lt; max1 &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="补充-1"   >          <a href="#补充-1" class="heading-link"><i class="fas fa-link"></i></a><a href="#补充-1" class="headerlink" title="补充"></a>补充</h2>      <p>其实到这你就能过了，但是这题还可以优化。也就是进行剪枝。</p><p>如果剩下的所有数字都加上也不如当前最优解，直接返回</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> remaining = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = pos; i &lt;= n*m; i++) &#123;</span><br><span class="line">        <span class="type">int</span> rx = (i<span class="number">-1</span>) / m + <span class="number">1</span>;</span><br><span class="line">        <span class="type">int</span> ry = (i<span class="number">-1</span>) % m + <span class="number">1</span>;</span><br><span class="line">        remaining += a[rx][ry];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(sum + remaining &lt;= max1) <span class="keyword">return</span>;</span><br></pre></td></tr></table></div></figure>        <h1 id="奶酪"   >          <a href="#奶酪" class="heading-link"><i class="fas fa-link"></i></a><a href="#奶酪" class="headerlink" title="奶酪"></a>奶酪</h1>      <p>[P3958 <span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/P3958" >NOIP 2017 提高组] 奶酪 - 洛谷</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>        <h2 id="题意-13"   >          <a href="#题意-13" class="heading-link"><i class="fas fa-link"></i></a><a href="#题意-13" class="headerlink" title="题意"></a>题意</h2>      <p>我们需要判断老鼠能否通过奶酪中的空洞从下表面（z&#x3D;0）到达上表面（z&#x3D;h）。一个三维问题</p>        <h2 id="思路-13"   >          <a href="#思路-13" class="heading-link"><i class="fas fa-link"></i></a><a href="#思路-13" class="headerlink" title="思路"></a>思路</h2>      <p>题目说“如果两个空洞相切或是相交，则 Jerry 可以从其中一个空洞跑到另一个空洞，”</p><p>也就是说每个圆如果相切相交，就是可联通可到达的。能不能从下表面到上表面，其实就是一个寻找路径的问题。特别的，路径有不同的起点和终点。</p><p>起点要求，对应的圆要和下表面相切或者相交，终点要求，对应的圆要和上表面相切或者相交。这里我们可以用一个数组分别标记一下可以作为起点终点的圆。</p><p>那我们可以预处理一下，通过距离判断，从一个圆可以到哪个圆，到这里你有没有想到邻接矩阵？</p><p>开始建图！</p>        <h3 id="1-问题转化"   >          <a href="#1-问题转化" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-问题转化" class="headerlink" title="1. 问题转化"></a>1. 问题转化</h3>      <ul><li>将每个空洞看作图中的一个节点</li><li>如果两个空洞相交或相切，则在对应节点间建立无向边</li><li>如果空洞与下表面接触，将其加入起点集合</li><li>如果空洞与上表面接触，将其加入终点集合</li></ul>        <h3 id="2-关键判断条件"   >          <a href="#2-关键判断条件" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-关键判断条件" class="headerlink" title="2. 关键判断条件"></a>2. 关键判断条件</h3>      <ul><li><strong>空洞相交判断</strong>：两空洞中心距离 ≤ 2r（即距离平方 ≤ 4r²）</li><li><strong>与表面接触判断</strong>：<ul><li>下表面：空洞底部 z ≤ r</li><li>上表面：空洞顶部 z ≥ h - r</li></ul></li></ul>        <h3 id="3-算法流程"   >          <a href="#3-算法流程" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-算法流程" class="headerlink" title="3. 算法流程"></a>3. 算法流程</h3>      <ol><li>读入所有空洞坐标</li><li>找出所有与上下表面接触的空洞</li><li>建立邻接矩阵表示空洞间的连通关系</li><li>对每对起点和终点进行DFS搜索</li><li>如果找到任意一条连通路径则输出”Yes”，否则输出”No”</li></ol>        <h3 id="4-dfs构造"   >          <a href="#4-dfs构造" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-dfs构造" class="headerlink" title="4.dfs构造"></a>4.dfs构造</h3>      <ul><li>参数设置：由于是寻找路径问题，我们令current为当前所在节点，target为目标节点</li><li>终止条件：当前节点等于目标节点时返回</li><li>遍历：遍历所有相邻结点，已经走过的用vis标记</li></ul>        <h2 id="代码-9"   >          <a href="#代码-9" class="heading-link"><i class="fas fa-link"></i></a><a href="#代码-9" class="headerlink" title="代码"></a>代码</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">int</span> n, h, r;           <span class="comment">// n:空洞数量, h:奶酪高度, r:空洞半径</span></span><br><span class="line"><span class="type">bool</span> flag;             <span class="comment">// 标记是否能从下表面到达上表面</span></span><br><span class="line"><span class="type">bool</span> adj[<span class="number">1005</span>][<span class="number">1005</span>];  <span class="comment">// 邻接矩阵，记录空洞之间的连通关系</span></span><br><span class="line"><span class="type">bool</span> vis[<span class="number">1005</span>];        <span class="comment">// 访问标记数组，用于DFS</span></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">point</span> &#123;</span><br><span class="line">    <span class="type">int</span> x, y, z;       <span class="comment">// 空洞的球心坐标</span></span><br><span class="line">&#125; a[<span class="number">1005</span>];</span><br><span class="line"></span><br><span class="line">vector&lt;<span class="type">int</span>&gt; down;      <span class="comment">// 存储与下表面接触的空洞编号</span></span><br><span class="line">vector&lt;<span class="type">int</span>&gt; up;        <span class="comment">// 存储与上表面接触的空洞编号</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// cur: 当前访问的空洞编号</span></span><br><span class="line"><span class="comment">// target: 目标空洞编号</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> cur, <span class="type">int</span> target)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 如果当前空洞就是目标空洞，设置标志并返回</span></span><br><span class="line">    <span class="keyword">if</span> (cur == target) &#123;</span><br><span class="line">        flag = <span class="literal">true</span>;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    vis[cur] = <span class="literal">true</span>;  <span class="comment">// 标记当前空洞已访问</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 遍历所有可能的相邻空洞</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        <span class="comment">// 如果当前空洞与空洞i连通且空洞i未被访问</span></span><br><span class="line">        <span class="keyword">if</span> (adj[cur][i] &amp;&amp; !vis[i]) &#123;</span><br><span class="line">            <span class="built_in">dfs</span>(i, target);  <span class="comment">// 递归搜索</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 输入输出优化</span></span><br><span class="line">    ios_base::<span class="built_in">sync_with_stdio</span>(<span class="literal">false</span>);</span><br><span class="line">    cin.<span class="built_in">tie</span>(<span class="literal">NULL</span>);</span><br><span class="line">    cout.<span class="built_in">tie</span>(<span class="literal">NULL</span>);</span><br><span class="line">    </span><br><span class="line">    <span class="type">int</span> t;  <span class="comment">// 测试用例数量</span></span><br><span class="line">    cin &gt;&gt; t;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 处理每个测试用例</span></span><br><span class="line">    <span class="keyword">while</span> (t--) &#123;</span><br><span class="line">        <span class="comment">// 初始化变量</span></span><br><span class="line">        flag = <span class="literal">false</span>;</span><br><span class="line">        <span class="built_in">memset</span>(adj, <span class="literal">false</span>, <span class="built_in">sizeof</span>(adj));  <span class="comment">// 重置邻接矩阵</span></span><br><span class="line">        down.<span class="built_in">clear</span>();  <span class="comment">// 清空下表面接触空洞列表</span></span><br><span class="line">        up.<span class="built_in">clear</span>();    <span class="comment">// 清空上表面接触空洞列表</span></span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 读入基本数据</span></span><br><span class="line">        cin &gt;&gt; n &gt;&gt; h &gt;&gt; r;</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 读入每个空洞的坐标并分类</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">            cin &gt;&gt; a[i].x &gt;&gt; a[i].y &gt;&gt; a[i].z;</span><br><span class="line">            </span><br><span class="line">            <span class="comment">// 判断空洞是否与下表面接触：空洞底部在或低于下表面</span></span><br><span class="line">            <span class="keyword">if</span> (a[i].z &lt;= r) &#123;</span><br><span class="line">                down.<span class="built_in">push_back</span>(i);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">// 判断空洞是否与上表面接触：空洞顶部在或高于上表面</span></span><br><span class="line">            <span class="keyword">if</span> (a[i].z &gt;= h - r) &#123;</span><br><span class="line">                up.<span class="built_in">push_back</span>(i);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 建立邻接矩阵：判断每对空洞是否连通</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> j = i + <span class="number">1</span>; j &lt;= n; j++) &#123;</span><br><span class="line">                <span class="comment">// 计算两个空洞中心距离的平方（使用long long防止溢出）</span></span><br><span class="line">                <span class="type">long</span> <span class="type">long</span> dist_sq = (<span class="type">long</span> <span class="type">long</span>)(a[i].x - a[j].x) * (a[i].x - a[j].x) +</span><br><span class="line">                                   (<span class="type">long</span> <span class="type">long</span>)(a[i].y - a[j].y) * (a[i].y - a[j].y) +</span><br><span class="line">                                   (<span class="type">long</span> <span class="type">long</span>)(a[i].z - a[j].z) * (a[i].z - a[j].z);</span><br><span class="line">                <span class="type">long</span> <span class="type">long</span> r_sq = (<span class="type">long</span> <span class="type">long</span>)<span class="number">4</span> * r * r;  <span class="comment">// 两个半径之和的平方：(2r)² = 4r²</span></span><br><span class="line">                </span><br><span class="line">                <span class="comment">// 如果距离平方 ≤ 4r²，说明两个空洞相交或相切</span></span><br><span class="line">                <span class="keyword">if</span> (dist_sq &lt;= r_sq) &#123;</span><br><span class="line">                    adj[i][j] = <span class="literal">true</span>;  <span class="comment">// 标记为连通</span></span><br><span class="line">                    adj[j][i] = <span class="literal">true</span>;  <span class="comment">// 无向图，双向标记</span></span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 检查是否能从下表面通往上表面</span></span><br><span class="line">        <span class="comment">// 遍历所有下表面接触空洞和上表面接触空洞的组合</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; down.<span class="built_in">size</span>() &amp;&amp; !flag; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">0</span>; j &lt; up.<span class="built_in">size</span>() &amp;&amp; !flag; j++) &#123;</span><br><span class="line">                <span class="built_in">memset</span>(vis, <span class="literal">false</span>, <span class="built_in">sizeof</span>(vis));  <span class="comment">// 重置访问标记</span></span><br><span class="line">                <span class="built_in">dfs</span>(down[i], up[j]);  <span class="comment">// 从下表面空洞DFS搜索到上表面空洞</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 输出结果</span></span><br><span class="line">        <span class="keyword">if</span> (flag) &#123;</span><br><span class="line">            cout &lt;&lt; <span class="string">&quot;Yes&quot;</span> &lt;&lt; endl;  <span class="comment">// 存在连通路径</span></span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            cout &lt;&lt; <span class="string">&quot;No&quot;</span> &lt;&lt; endl;   <span class="comment">// 不存在连通路径</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="补充-2"   >          <a href="#补充-2" class="heading-link"><i class="fas fa-link"></i></a><a href="#补充-2" class="headerlink" title="补充"></a>补充</h2>      <p>其实这道题还有并查集写法，但是普通的并查集会超时，这里只做示范用，代码过不了评测。</p>        <h3 id="并查集原理"   >          <a href="#并查集原理" class="heading-link"><i class="fas fa-link"></i></a><a href="#并查集原理" class="headerlink" title="并查集原理"></a>并查集原理</h3>      <p>并查集是一种用于管理分组的高效数据结构，支持两种操作：</p><ul><li><code>find(x)</code>：查找x所在的集合代表</li><li><code>unite(x, y)</code>：合并x和y所在的集合</li></ul>        <h3 id="1-数据结构定义"   >          <a href="#1-数据结构定义" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-数据结构定义" class="headerlink" title="1. 数据结构定义"></a>1. 数据结构定义</h3>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">struct</span> <span class="title class_">Point</span> &#123;</span><br><span class="line">    <span class="type">long</span> <span class="type">long</span> x, y, z;  <span class="comment">// 使用long long防止计算溢出</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">vector&lt;<span class="type">int</span>&gt; parent;  <span class="comment">// 并查集父节点数组</span></span><br></pre></td></tr></table></div></figure>        <h3 id="2-并查集核心操作"   >          <a href="#2-并查集核心操作" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-并查集核心操作" class="headerlink" title="2. 并查集核心操作"></a>2. 并查集核心操作</h3>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 查找操作：带路径压缩</span></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">find</span><span class="params">(<span class="type">int</span> x)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> parent[x] == x ? x : parent[x] = <span class="built_in">find</span>(parent[x]);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 合并操作</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">unite</span><span class="params">(<span class="type">int</span> x, <span class="type">int</span> y)</span> </span>&#123;</span><br><span class="line">    x = <span class="built_in">find</span>(x);</span><br><span class="line">    y = <span class="built_in">find</span>(y);</span><br><span class="line">    <span class="keyword">if</span> (x != y) parent[y] = x;  <span class="comment">// 将y的集合合并到x的集合</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h3 id="3-主算法流程"   >          <a href="#3-主算法流程" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-主算法流程" class="headerlink" title="3. 主算法流程"></a>3. 主算法流程</h3>              <h4 id="初始化"   >          <a href="#初始化" class="heading-link"><i class="fas fa-link"></i></a><a href="#初始化" class="headerlink" title="初始化"></a>初始化</h4>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">parent.<span class="built_in">resize</span>(n + <span class="number">2</span>);  <span class="comment">// 节点0:下表面, 节点n+1:上表面, 节点1-n:空洞</span></span><br><span class="line"><span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt;= n + <span class="number">1</span>; i++) </span><br><span class="line">    parent[i] = i;     <span class="comment">// 初始时每个节点自成一个集合</span></span><br></pre></td></tr></table></div></figure>        <h4 id="连接表面与空洞"   >          <a href="#连接表面与空洞" class="heading-link"><i class="fas fa-link"></i></a><a href="#连接表面与空洞" class="headerlink" title="连接表面与空洞"></a>连接表面与空洞</h4>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">    cin &gt;&gt; points[i].x &gt;&gt; points[i].y &gt;&gt; points[i].z;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 与下表面接触：空洞底部 z ≤ r</span></span><br><span class="line">    <span class="keyword">if</span> (points[i].z &lt;= r) <span class="built_in">unite</span>(<span class="number">0</span>, i);</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 与上表面接触：空洞顶部 z ≥ h - r  </span></span><br><span class="line">    <span class="keyword">if</span> (points[i].z &gt;= h - r) <span class="built_in">unite</span>(n + <span class="number">1</span>, i);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h4 id="连接相交的空洞"   >          <a href="#连接相交的空洞" class="heading-link"><i class="fas fa-link"></i></a><a href="#连接相交的空洞" class="headerlink" title="连接相交的空洞"></a>连接相交的空洞</h4>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> j = i + <span class="number">1</span>; j &lt;= n; j++) &#123;</span><br><span class="line">        <span class="type">long</span> <span class="type">long</span> dx = points[i].x - points[j].x;</span><br><span class="line">        <span class="type">long</span> <span class="type">long</span> dy = points[i].y - points[j].y;</span><br><span class="line">        <span class="type">long</span> <span class="type">long</span> dz = points[i].z - points[j].z;</span><br><span class="line">        <span class="comment">// 判断条件：两空洞中心距离 ≤ 2r</span></span><br><span class="line">        <span class="keyword">if</span> (dx*dx + dy*dy + dz*dz &lt;= <span class="number">4LL</span> * r * r) &#123;</span><br><span class="line">            <span class="built_in">unite</span>(i, j);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h4 id="结果判断"   >          <a href="#结果判断" class="heading-link"><i class="fas fa-link"></i></a><a href="#结果判断" class="headerlink" title="结果判断"></a>结果判断</h4>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (<span class="built_in">find</span>(<span class="number">0</span>) == <span class="built_in">find</span>(n + <span class="number">1</span>)) &#123;</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;Yes&quot;</span> &lt;&lt; endl;  <span class="comment">// 下表面和上表面连通</span></span><br><span class="line">&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;No&quot;</span> &lt;&lt; endl;   <span class="comment">// 不连通</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>]]></content>
      
      
      <categories>
          
          <category> 算法 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 算法 </tag>
            
            <tag> acm </tag>
            
            <tag> 数据结构 </tag>
            
            <tag> dfs </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>喵喵思维题</title>
      <link href="/2025/11/21/%E6%80%9D%E7%BB%B4%E9%A2%98/"/>
      <url>/2025/11/21/%E6%80%9D%E7%BB%B4%E9%A2%98/</url>
      
        <content type="html"><![CDATA[        <h1 id="L-Palm-Island"   >          <a href="#L-Palm-Island" class="heading-link"><i class="fas fa-link"></i></a><a href="#L-Palm-Island" class="headerlink" title="L.Palm Island"></a>L.Palm Island</h1>      <p><span class="exturl"><a class="exturl__link"   href="https://codeforces.com/gym/104813/problem/L" >2023哈尔滨ccpc</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p><p>有一个字符串，可以把第一个字符移动到最后一个，也可以把最后一个字符移动到最后一个。前者为1操作，后者为2操作。假设字符串长度为n，你需要输出一个由12组成的序列（长度不超过n方），</p><p>带有模拟思想的构造。</p><p>这种题目往往你需要想出一种易于模拟的想法，然后用代码实现。如果你面对一个序列，要变成目标序列，只能这两个操作，你会怎么办？</p><p>**注意到你有n方的操作机会。**也就意味着，你可以双重循环暴力。所以你根本不用考虑最优解法，非常暴力的模拟即可。</p><p>我们现在重新来看这两个操作，表面上只能操作序号1，2的字符，但是我们可以通过不断循环，让3，4也变成1，2。<strong>那么就有了一个初步的思路</strong>。</p><blockquote><p>把你的目标牌通过1操作移到牌顶，然后不断进行2操作就可以修改目标牌后对应的数字，直到目标牌的后一位对应自己应该对应的数字。执行完之后，再直接两个操作一，进行下一对数字的匹配。</p></blockquote><p>对于目标牌，由于我们不需要考虑时间复杂度，所以不需要想先选择哪个作为目标牌。直接按照目标牌的遍历。如果顶部的牌不是目标牌，进行操作一，当成为目标牌后，然后不断操作二，把操控第二位数字。然后1，2就正确了。</p><p>但是聪明的你有没有发现一个问题。<strong>如果目标牌固定好后，我把应该在他后面的数字放到第二位然后继续循环会发生什么</strong></p><ol><li><strong>逻辑混乱</strong>：我们试图同时控制”当前目标牌”和”它的后继”，但操作2实际上影响的是底部牌</li><li><strong>破坏已固定的关系</strong>：当我们调整第二位时，实际上在改变整个序列的后面部分，破坏了之前建立的关系</li><li><strong>缺乏稳定性</strong>：没有固定的”锚点”来保持已匹配部分的位置。</li></ol><p>这样说也许有点抽象。</p><p>假设：</p><ul><li>初始序列：[1, 2, 3, 4]</li><li>目标序列：[3, 1, 4, 2]</li><li><img src="/../images/image-20251121102336069.png" alt="image-20251121102336069"></li></ul><p>可以看到这样会打乱我们已经匹配好的。所以我们需要避免这个问题。</p><p>我们每次把目标牌移到顶部，然后不断操作二，其实可以看作是在调整底部牌，为什么要调整底部牌呢？</p><p><strong>因为我们要固定已经匹配好的牌</strong></p><p>想象一下，我们每次匹配好一对牌后，希望这对牌的位置关系不再改变。通过把已经匹配好的牌放到底部，它们就不会被后续的操作影响到底部以上的部分。</p><p><strong>再深入思考一下</strong>：操作1是整体旋转，操作2是跳过第一张牌调整后面的顺序。这两个操作结合起来，就能让我们像**“冒泡排序**”（划重点）一样，逐步把正确的牌放到正确的位置。</p><p><strong>具体执行过程</strong>：</p><ol><li>我们按顺序处理目标序列的第2到第n张牌</li><li>对于每个目标位置i，我们先把b[i]牌转到顶部（操作1）</li><li>然后调整底部，让b[i-1]牌到底部（操作2）（这样相对位置就对了，只需要后期1操作循环即可）</li><li>这样b[i-1]和b[i]的相对位置就固定了</li></ol><p><strong>直观理解一下。</strong></p><p><img src="/../images/image-20251121103040791.png" alt="image-20251121103040791"></p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">2</span>; i &lt;= n; i++)&#123;</span><br><span class="line">    <span class="comment">// 步骤1：旋转直到顶部是目标第i张牌</span></span><br><span class="line">    <span class="keyword">while</span>(顶部牌 != b[i]) 执行操作<span class="number">1</span>;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 步骤2：调整直到底部是目标第i-1张牌  </span></span><br><span class="line">    <span class="keyword">while</span>(底部牌 != b[i<span class="number">-1</span>]) 执行操作<span class="number">2</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 最后调整：旋转直到顶部是目标第一张牌</span></span><br><span class="line"><span class="keyword">while</span>(顶部牌 != b[<span class="number">1</span>]) 执行操作<span class="number">1</span>;</span><br></pre></td></tr></table></div></figure><p>附上AC代码</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">1005</span>;</span><br><span class="line"><span class="type">int</span> a[N], b[N], n;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">op1</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="type">int</span> t = a[<span class="number">1</span>];</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">2</span>; i &lt;= n; i++) a[i<span class="number">-1</span>] = a[i];</span><br><span class="line">    a[n] = t;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">op2</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="type">int</span> t = a[<span class="number">2</span>];</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">2</span>; i &lt; n; i++) a[i] = a[i<span class="number">+1</span>];</span><br><span class="line">    a[n] = t;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    ios::<span class="built_in">sync_with_stdio</span>(<span class="literal">false</span>);</span><br><span class="line">    cin.<span class="built_in">tie</span>(<span class="number">0</span>);</span><br><span class="line">    </span><br><span class="line">    <span class="type">int</span> t;</span><br><span class="line">    cin &gt;&gt; t;</span><br><span class="line">    <span class="keyword">while</span>(t--) &#123;</span><br><span class="line">        cin &gt;&gt; n;</span><br><span class="line">        vector&lt;<span class="type">int</span>&gt; ans;</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) cin &gt;&gt; a[i];</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) cin &gt;&gt; b[i];</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">2</span>; i &lt;= n; i++) &#123;</span><br><span class="line">            <span class="keyword">while</span>(a[<span class="number">1</span>] != b[i]) &#123;</span><br><span class="line">                <span class="built_in">op1</span>();</span><br><span class="line">                ans.<span class="built_in">push_back</span>(<span class="number">1</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">while</span>(a[n] != b[i<span class="number">-1</span>]) &#123;</span><br><span class="line">                <span class="built_in">op2</span>();</span><br><span class="line">                ans.<span class="built_in">push_back</span>(<span class="number">2</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">while</span>(a[<span class="number">1</span>] != b[<span class="number">1</span>]) &#123;</span><br><span class="line">            <span class="built_in">op1</span>();</span><br><span class="line">            ans.<span class="built_in">push_back</span>(<span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">auto</span> x : ans) cout &lt;&lt; x;</span><br><span class="line">        cout &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="B-Memory"   >          <a href="#B-Memory" class="heading-link"><i class="fas fa-link"></i></a><a href="#B-Memory" class="headerlink" title="B.Memory"></a>B.Memory</h1>      <p><span class="exturl"><a class="exturl__link"   href="https://codeforces.com/gym/104813/problem/L" >2023哈尔滨ccpc</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p><p><img src="/../images/image-20251121130940238.png" alt="image-20251121130940238"></p><p>给一串数字，求Mood。</p><p>一眼暴力的话，其实很简单写。你可能会注意到小数的精度问题。（心存侥幸的话你会这么写）</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> (<span class="type">int</span> i = n;i &gt;= <span class="number">1</span>;i--)&#123;</span><br><span class="line">    result = a[i] * <span class="built_in">pow</span>(<span class="number">2</span>,zz);</span><br><span class="line">    zz--;</span><br><span class="line">    sum += result;</span><br><span class="line">&#125;</span><br><span class="line">b[n] = sum;</span><br><span class="line"><span class="keyword">for</span>(<span class="type">int</span> i = n;i &gt;= <span class="number">1</span>;i--)&#123;</span><br><span class="line">    b[i<span class="number">-1</span>]=(b[i]-a[i])*<span class="number">2.0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>（注意到其实是有递归关系的，mood[i]-a[i]再×2就可以得到mood[i-1]<strong>。这是一个递归关系</strong>。虽然你喜提wa3，但是你得到了一个很重要的递归关系。</p><p>又注意到mood×上一个正整数不改变符号，那我×2的n方不就没小数了。而且这样还很便捷的可以×上幂部分。但是你大概估算就知道显然也会整数溢出。恭喜wa3。</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">string result = <span class="string">&quot;&quot;</span>;</span><br><span class="line">   <span class="type">long</span> <span class="type">long</span> sum = <span class="number">0</span>;</span><br><span class="line">   <span class="type">long</span> <span class="type">long</span> power = <span class="number">2</span>; <span class="comment">// 2^1</span></span><br><span class="line">   </span><br><span class="line">   <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">       sum += a[i] * power;</span><br><span class="line">       </span><br><span class="line">       <span class="keyword">if</span> (sum &lt; <span class="number">0</span>) &#123;</span><br><span class="line">           result += <span class="string">&#x27;-&#x27;</span>;</span><br><span class="line">       &#125; <span class="keyword">else</span> <span class="keyword">if</span> (sum &gt; <span class="number">0</span>) &#123;</span><br><span class="line">           result += <span class="string">&#x27;+&#x27;</span>;</span><br><span class="line">       &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">           result += <span class="string">&#x27;0&#x27;</span>;</span><br><span class="line">       &#125;</span><br><span class="line">       </span><br><span class="line">       <span class="keyword">if</span> (i &lt; n) power *= <span class="number">2</span>;</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></div></figure><p>从这两次失败我们可以看出，算出每个mood再判断符号肯定不行，我们需要有一个巧妙的办法。</p><p>整数数字太大会移除，浮点数的精度不够，小数点可能有很多位。</p><p><strong>那么两者结合一下，如果浮点数是整数，不就不用考虑精度，而且不用担心数字太大了？</strong></p><p>简单来说就是把1.00000001变成1，这样并不会改变符号。</p><p><strong>也就是整数截断</strong>，然后用</p><p>但是你可能有问题，忽略小数点后的数字最后累积起来不会影响最后正负吗？</p><p>我想告诉你的是，如果采用递归，每次加上新的整数，误差都会被重置。</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    ios::<span class="built_in">sync_with_stdio</span>(<span class="literal">false</span>);</span><br><span class="line">    cin.<span class="built_in">tie</span>(<span class="number">0</span>);</span><br><span class="line">    </span><br><span class="line">    <span class="type">int</span> n;</span><br><span class="line">    cin &gt;&gt; n;</span><br><span class="line">    </span><br><span class="line">    <span class="type">int</span> val = <span class="number">0</span>;    <span class="comment">// 当前 Mood 的整数部分</span></span><br><span class="line">    <span class="type">int</span> sig = <span class="number">0</span>;    <span class="comment">// 小数部分的符号趋势</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        <span class="type">int</span> x;</span><br><span class="line">        cin &gt;&gt; x;</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 如果是奇数，记录小数部分符号</span></span><br><span class="line">        <span class="keyword">if</span> (val % <span class="number">2</span> != <span class="number">0</span>) &#123;</span><br><span class="line">            sig = (val &gt; <span class="number">0</span>) ? <span class="number">1</span> : <span class="number">-1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 递推计算</span></span><br><span class="line">        val = val / <span class="number">2</span> + x;</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 判断符号</span></span><br><span class="line">        <span class="keyword">if</span> (val == <span class="number">0</span> &amp;&amp; sig == <span class="number">0</span>) &#123;</span><br><span class="line">            cout &lt;&lt; <span class="string">&#x27;0&#x27;</span>;        <span class="comment">// 精确为0</span></span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> (val &gt;= <span class="number">1</span> || (val == <span class="number">0</span> &amp;&amp; sig == <span class="number">1</span>)) &#123;</span><br><span class="line">            cout &lt;&lt; <span class="string">&#x27;+&#x27;</span>;        <span class="comment">// 正数</span></span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            cout &lt;&lt; <span class="string">&#x27;-&#x27;</span>;        <span class="comment">// 负数</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>]]></content>
      
      
      <categories>
          
          <category> 算法 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 算法 </tag>
            
            <tag> acm </tag>
            
            <tag> 思维题 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>前端基础</title>
      <link href="/2025/11/18/%E5%89%8D%E7%AB%AF/"/>
      <url>/2025/11/18/%E5%89%8D%E7%AB%AF/</url>
      
        <content type="html"><![CDATA[<p>用来记录一下自己的前端入门阶段</p>        <h1 id="html"   >          <a href="#html" class="heading-link"><i class="fas fa-link"></i></a><a href="#html" class="headerlink" title="html"></a>html</h1>      <p>我用的vscode写的html，这里推荐安装一款插件，可以实时看到网页效果（HTML preview）</p><p><img src="/../images/image-20251118084723711.png" alt="image-20251118084723711"></p><p><img src="/../images/image-20251118084956640.png" alt="image-20251118084956640"></p><p>html和CSS实在是没什么好说的，直接贴上代码</p><figure class="highlight html"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;en&quot;</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">name</span>=<span class="string">&quot;viewport&quot;</span> <span class="attr">content</span>=<span class="string">&quot;width=device-width, initial-scale=1.0&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>Document<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;todo-app&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;title&quot;</span>&gt;</span></span><br><span class="line">            jade&#x27;s Todo list</span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;todo-from&quot;</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">input</span> <span class="attr">class</span>=<span class="string">&quot;todo-input&quot;</span><span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">placeholder</span>=<span class="string">&quot;Add a todo&quot;</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;todo-buttom&quot;</span>&gt;</span>add todo<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;item completed&quot;</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;checkbox&quot;</span>&gt;</span></span><br><span class="line">            <span class="comment">&lt;!--span避免换行，横着排的。吃饭只是文本内容，不需要块级元素的属性--&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">span</span> <span class="attr">class</span>=<span class="string">&quot;name&quot;</span>&gt;</span>吃饭<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            </span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;del&quot;</span>&gt;</span>del<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;item &quot;</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;checkbox&quot;</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">span</span> <span class="attr">class</span>=<span class="string">&quot;name&quot;</span>&gt;</span>睡觉<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            </span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;del&quot;</span>&gt;</span>del<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;item &quot;</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;checkbox&quot;</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">span</span> <span class="attr">class</span>=<span class="string">&quot;name&quot;</span>&gt;</span>打游戏<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            </span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;del&quot;</span>&gt;</span>del<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"></span><br><span class="line">   </span><br><span class="line">    <span class="tag">&lt;<span class="name">style</span>&gt;</span><span class="language-css"> </span></span><br><span class="line"><span class="language-css">    <span class="selector-class">.completed</span>&#123;</span></span><br><span class="line"><span class="language-css">        <span class="comment">/*字上划线*/</span></span></span><br><span class="line"><span class="language-css">        <span class="attribute">text-decoration</span>: line-through;</span></span><br><span class="line"><span class="language-css">        <span class="comment">/*透明度*/</span></span></span><br><span class="line"><span class="language-css">        <span class="attribute">opacity</span>: <span class="number">0.4</span>;</span></span><br><span class="line"><span class="language-css">    &#125;</span></span><br><span class="line"><span class="language-css">    <span class="selector-class">.item</span>&#123;</span></span><br><span class="line"><span class="language-css">        <span class="selector-class">.del</span>&#123;</span></span><br><span class="line"><span class="language-css">            <span class="attribute">color</span>: <span class="number">#0aa76ee1</span>;</span></span><br><span class="line"><span class="language-css">        &#125;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">display</span>: flex;</span></span><br><span class="line"><span class="language-css">        <span class="comment">/*垂直时居中*/</span></span></span><br><span class="line"><span class="language-css">        <span class="attribute">align-items</span>: center;</span></span><br><span class="line"><span class="language-css">        <span class="comment">/*框中元素平分空间*/</span></span></span><br><span class="line"><span class="language-css">        <span class="attribute">justify-content</span>: space-between;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">box-sizing</span>: border-box;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">width</span>:<span class="number">80%</span>;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">height</span>: <span class="number">60px</span>;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">padding</span>: <span class="number">16px</span>;</span></span><br><span class="line"><span class="language-css">        <span class="comment">/*margin可以有四个参数，左上开始顺时针。两个参数时第一个表示上下，第二个左右，auto表示自适应*/</span></span></span><br><span class="line"><span class="language-css">        <span class="attribute">margin</span>: <span class="number">8px</span> auto;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">border-radius</span>: <span class="number">20px</span>;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">background-color</span>: white;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">box-shadow</span>: <span class="built_in">rgba</span>(<span class="number">15</span>, <span class="number">131</span>, <span class="number">247</span>, <span class="number">0.2</span>)<span class="number">8px</span> <span class="number">8px</span> <span class="number">20px</span>;</span></span><br><span class="line"><span class="language-css">    &#125;</span></span><br><span class="line"><span class="language-css">    <span class="selector-class">.todo-buttom</span>&#123;</span></span><br><span class="line"><span class="language-css">        <span class="comment">/* 左侧内边距*/</span></span></span><br><span class="line"><span class="language-css">         <span class="attribute">padding-left</span>: <span class="number">10px</span>;</span></span><br><span class="line"><span class="language-css">         <span class="comment">/*圆角*/</span></span></span><br><span class="line"><span class="language-css">        <span class="attribute">border-radius</span>: <span class="number">0</span> <span class="number">20px</span> <span class="number">20px</span> <span class="number">0</span>;</span></span><br><span class="line"><span class="language-css">        <span class="comment">/*去除轮廓*/</span></span></span><br><span class="line"><span class="language-css">        <span class="attribute">outline</span>:none;</span></span><br><span class="line"><span class="language-css">        <span class="comment">/*宽度*/</span></span></span><br><span class="line"><span class="language-css">        <span class="attribute">width</span>: <span class="number">10%</span>;</span></span><br><span class="line"><span class="language-css">        <span class="comment">/*高度*/</span>  </span></span><br><span class="line"><span class="language-css">        <span class="attribute">height</span>: <span class="number">50px</span>;</span></span><br><span class="line"><span class="language-css">        <span class="comment">/*背景颜色*/</span></span></span><br><span class="line"><span class="language-css">        <span class="attribute">background-color</span>: aqua;</span></span><br><span class="line"><span class="language-css">        <span class="comment">/*横向排列*/</span></span></span><br><span class="line"><span class="language-css">        <span class="attribute">display</span>: flex;</span></span><br><span class="line"><span class="language-css">        <span class="comment">/*居中*/</span></span></span><br><span class="line"><span class="language-css">        <span class="attribute">align-items</span>: center;</span></span><br><span class="line"><span class="language-css">        <span class="comment">/*鼠标悬停变小手.表示可点击*/</span></span></span><br><span class="line"><span class="language-css">        <span class="attribute">cursor</span>: pointer;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">user-select</span>: none;</span></span><br><span class="line"><span class="language-css">    &#125;</span></span><br><span class="line"><span class="language-css">    <span class="selector-class">.todo-input</span>&#123;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">margin-bottom</span>: <span class="number">10px</span>;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">padding-left</span>: <span class="number">10px</span>;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">box-sizing</span>: border-box;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">border-radius</span>: <span class="number">20px</span> <span class="number">0</span> <span class="number">0</span> <span class="number">20px</span>;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">outline</span>:none;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">width</span>: <span class="number">60%</span>;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">height</span>: <span class="number">50px</span>;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">border</span>:<span class="number">1px</span> solid <span class="built_in">rgb</span>(<span class="number">0</span>, <span class="number">145</span>, <span class="number">255</span>);</span></span><br><span class="line"><span class="language-css">    &#125;</span></span><br><span class="line"><span class="language-css">    <span class="selector-class">.todo-from</span>&#123;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">display</span>: flex;</span></span><br><span class="line"><span class="language-css">         <span class="attribute">padding-left</span>: <span class="number">20px</span>;</span></span><br><span class="line"><span class="language-css">    &#125;</span></span><br><span class="line"><span class="language-css">     <span class="selector-tag">body</span>&#123;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">background-image</span>: <span class="built_in">linear-gradient</span>(to right,<span class="built_in">rgb</span>(<span class="number">0</span>, <span class="number">145</span>, <span class="number">255</span>), <span class="number">#51c69b</span>);</span></span><br><span class="line"><span class="language-css">        <span class="attribute">min-height</span>: <span class="number">100vh</span>;</span></span><br><span class="line"><span class="language-css">        <span class="attribute">margin</span>:<span class="number">0</span>;</span></span><br><span class="line"><span class="language-css">     &#125;</span></span><br><span class="line"><span class="language-css">     <span class="selector-class">.todo-app</span>&#123;</span></span><br><span class="line"><span class="language-css">         <span class="attribute">width</span>: <span class="number">98%</span>;</span></span><br><span class="line"><span class="language-css">         <span class="attribute">height</span>: <span class="number">700px</span>;</span></span><br><span class="line"><span class="language-css">         <span class="attribute">background-color</span>: white;</span></span><br><span class="line"><span class="language-css">         <span class="attribute">border-radius</span>: <span class="number">10px</span>;</span></span><br><span class="line"><span class="language-css">         <span class="attribute">margin-top</span>: <span class="number">40px</span>;</span></span><br><span class="line"><span class="language-css">         <span class="attribute">margin-left</span>: <span class="number">1%</span>;</span></span><br><span class="line"><span class="language-css">     &#125;</span></span><br><span class="line"><span class="language-css">     <span class="selector-class">.title</span>&#123;</span></span><br><span class="line"><span class="language-css">        <span class="comment">/* 字体大小 */</span></span></span><br><span class="line"><span class="language-css">         <span class="attribute">font-size</span>: <span class="number">30px</span>;</span></span><br><span class="line"><span class="language-css">         <span class="comment">/* 字体颜色 */</span></span></span><br><span class="line"><span class="language-css">         <span class="attribute">color</span>: <span class="number">#51c69b</span>;</span></span><br><span class="line"><span class="language-css">         <span class="comment">/* 字体粗细 */</span></span></span><br><span class="line"><span class="language-css">         <span class="attribute">font-weight</span>: <span class="number">600</span>;</span></span><br><span class="line"><span class="language-css">         <span class="comment">/* 字体居中 */</span></span></span><br><span class="line"><span class="language-css">         <span class="attribute">text-align</span>: center;</span></span><br><span class="line"><span class="language-css">         <span class="comment">/* 字体间距 */</span></span></span><br><span class="line"><span class="language-css">         <span class="attribute">letter-spacing</span>: <span class="number">2px</span>;</span></span><br><span class="line"><span class="language-css">         <span class="comment">/* 字体行高 */</span></span></span><br><span class="line"><span class="language-css">         <span class="attribute">line-height</span>: <span class="number">50px</span>;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css">     &#125;</span></span><br><span class="line"><span class="language-css">    </span><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></div></figure>        <h1 id="vue"   >          <a href="#vue" class="heading-link"><i class="fas fa-link"></i></a><a href="#vue" class="headerlink" title="vue"></a>vue</h1>      <p>到此一份静态网页就成功了，为了让他可交互的动起来，我们需要用vue</p><p>在此之前，需要了解一些知识。</p>        <h2 id="基础知识"   >          <a href="#基础知识" class="heading-link"><i class="fas fa-link"></i></a><a href="#基础知识" class="headerlink" title="基础知识"></a>基础知识</h2>              <h3 id="1-Vue-3-Composition-API-基础"   >          <a href="#1-Vue-3-Composition-API-基础" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-Vue-3-Composition-API-基础" class="headerlink" title="1. Vue 3 Composition API 基础"></a>1. Vue 3 Composition API 基础</h3>              <h4 id="1-1-语法"   >          <a href="#1-1-语法" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-1-语法" class="headerlink" title="1.1 &lt;script setup&gt;语法"></a>1.1 <code>&lt;script setup&gt;</code>语法</h4>      <ul><li>这是Vue 3的编译时语法糖，简化了组件编写</li><li>无需显式返回数据和方法，更简洁的代码结构</li><li>自动将顶层变量&#x2F;函数暴露给模板</li></ul>        <h4 id="1-2-ref响应式数据"   >          <a href="#1-2-ref响应式数据" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-2-ref响应式数据" class="headerlink" title="1.2 ref响应式数据"></a>1.2 <code>ref</code>响应式数据</h4>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">import &#123; ref &#125; from &#x27;vue&#x27;</span><br><span class="line"></span><br><span class="line">const value = ref(&#x27;&#x27;) // 创建响应式数据</span><br><span class="line">const list = ref([...]) // 响应式数组</span><br></pre></td></tr></table></div></figure><p><strong>注意点：</strong></p><ul><li><code>ref</code>用于创建响应式的基本类型或对象类型数据</li><li>访问值时需要使用 <code>.value</code>（在模板中自动解包，无需.value）</li><li>修改值时必须通过 <code>.value</code>修改</li></ul>        <h3 id="2-数据定义与响应式原理"   >          <a href="#2-数据定义与响应式原理" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-数据定义与响应式原理" class="headerlink" title="2. 数据定义与响应式原理"></a>2. 数据定义与响应式原理</h3>              <h4 id="2-1-数据初始化"   >          <a href="#2-1-数据初始化" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-1-数据初始化" class="headerlink" title="2.1 数据初始化"></a>2.1 数据初始化</h4>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">const value = ref(&#x27;&#x27;) // 输入框的当前值</span><br><span class="line">const list = ref([</span><br><span class="line">  &#123; value: &#x27;吃饭&#x27;, isCompleted: true &#125;,</span><br><span class="line">  &#123; value: &#x27;睡觉&#x27;, isCompleted: false &#125;,</span><br><span class="line">  &#123; value: &#x27;打豆豆&#x27;, isCompleted: false &#125;,</span><br><span class="line">])</span><br></pre></td></tr></table></div></figure><p><strong>关键理解：</strong></p><ul><li><code>list</code>是一个响应式数组，数组变化会自动更新视图</li><li>每个待办项是对象，包含内容值和完成状态(名称可以自定义，比如value这些可以随意更改名字)</li></ul>        <h3 id="3-方法实现逻辑"   >          <a href="#3-方法实现逻辑" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-方法实现逻辑" class="headerlink" title="3. 方法实现逻辑"></a>3. 方法实现逻辑</h3>              <h4 id="3-1-添加待办事项-add函数"   >          <a href="#3-1-添加待办事项-add函数" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-1-添加待办事项-add函数" class="headerlink" title="3.1 添加待办事项 (add函数)"></a>3.1 添加待办事项 (<code>add</code>函数)</h4>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">function add() &#123;</span><br><span class="line">  list.value.push(&#123;</span><br><span class="line">    value: value.value,</span><br><span class="line">    isCompleted: false,</span><br><span class="line">  &#125;)</span><br><span class="line">  value.value = &#x27;&#x27; // 清空输入框</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>（这里要实现的功能是，把输入框的当前值放入数组，所以用到list.value.push(){}，然后用完输入框中的值要清空）</p><p><strong>实现原理：</strong></p><ol><li>从 <code>value.value</code>获取输入框的当前值</li><li>向 <code>list.value</code>数组添加新对象</li><li>清空输入框，准备下一次输入</li></ol>        <h4 id="3-2-删除待办事项-del函数"   >          <a href="#3-2-删除待办事项-del函数" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-2-删除待办事项-del函数" class="headerlink" title="3.2 删除待办事项 (del函数)"></a>3.2 删除待办事项 (<code>del</code>函数)</h4>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">function del(index) &#123;</span><br><span class="line">  list.value.splice(index, 1)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>（删除不能随意删除，每次只能删除一个，所以需要传入下标，每次删除对应下标的）</p><p><strong>实现原理：</strong></p><ul><li>通过 <code>splice(index, 1)</code>从数组中删除指定位置的元素</li><li>视图会自动更新，删除对应的DOM元素</li></ul>        <h3 id="4-模板语法详解"   >          <a href="#4-模板语法详解" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-模板语法详解" class="headerlink" title="4. 模板语法详解"></a>4. 模板语法详解</h3>              <h4 id="4-1-列表渲染-v-for"   >          <a href="#4-1-列表渲染-v-for" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-1-列表渲染-v-for" class="headerlink" title="4.1 列表渲染 (v-for)"></a>4.1 列表渲染 (<code>v-for</code>)</h4>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;div v-for=&quot;(item, index) in list&quot; :key=&quot;index&quot;&gt;</span><br><span class="line">  &lt;!-- 循环内容 --&gt;</span><br><span class="line">&lt;/div&gt;</span><br></pre></td></tr></table></div></figure><p><strong>重要概念：</strong></p><ul><li><code>v-for</code>用于循环渲染数组或对象</li><li><code>:key</code>是必须的，帮助Vue识别每个节点的身份，提高渲染性能</li><li>这里使用 <code>index</code>作为key（简单场景可用，但数据顺序变化时可能有性能问题）</li></ul>        <h4 id="4-2-动态类名绑定-class"   >          <a href="#4-2-动态类名绑定-class" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-2-动态类名绑定-class" class="headerlink" title="4.2 动态类名绑定 (:class)"></a>4.2 动态类名绑定 (<code>:class</code>)</h4>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;div :class=&quot;[item.isCompleted ? &#x27;completed&#x27; : &#x27;item&#x27;]&quot;&gt;</span><br></pre></td></tr></table></div></figure><p><strong>语法解析：</strong></p><ul><li>数组语法：根据条件返回不同的类名</li><li>当 <code>item.isCompleted</code>为true时应用 <code>completed</code>类</li><li>为false时应用 <code>item</code>类</li></ul>        <h4 id="4-3-双向数据绑定-v-model"   >          <a href="#4-3-双向数据绑定-v-model" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-3-双向数据绑定-v-model" class="headerlink" title="4.3 双向数据绑定 (v-model)"></a>4.3 双向数据绑定 (<code>v-model</code>)</h4>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;input v-model=&quot;value&quot; type=&quot;text&quot;&gt;</span><br><span class="line">&lt;input v-model=&quot;item.isCompleted&quot; type=&quot;checkbox&quot;&gt;</span><br></pre></td></tr></table></div></figure><p><strong>工作原理：</strong></p><ul><li>输入框：<code>v-model=&quot;value&quot;</code>绑定到响应式数据</li><li>复选框：<code>v-model=&quot;item.isCompleted&quot;</code>绑定到对象的完成状态</li><li>数据变化 → 视图更新，用户输入 → 数据更新</li></ul>        <h4 id="4-4-事件处理-click"   >          <a href="#4-4-事件处理-click" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-4-事件处理-click" class="headerlink" title="4.4 事件处理 (@click)"></a>4.4 事件处理 (<code>@click</code>)</h4>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;div @click=&quot;add&quot; class=&quot;todo-button&quot;&gt;Add Todo&lt;/div&gt;</span><br><span class="line">&lt;div @click=&quot;del(index)&quot; class=&quot;del&quot;&gt;del&lt;/div&gt;</span><br></pre></td></tr></table></div></figure><p><strong>事件传递：</strong></p><ul><li>点击”Add Todo”时调用 <code>add</code>函数</li><li>点击”del”时调用 <code>del(index)</code>并传入当前项的索引</li></ul>        <h3 id="5-样式处理技巧"   >          <a href="#5-样式处理技巧" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-样式处理技巧" class="headerlink" title="5. 样式处理技巧"></a>5. 样式处理技巧</h3>              <h4 id="5-1-scoped样式作用域"   >          <a href="#5-1-scoped样式作用域" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-1-scoped样式作用域" class="headerlink" title="5.1 scoped样式作用域"></a>5.1 <code>scoped</code>样式作用域</h4>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;style scoped&gt;</span><br><span class="line">/* 这里的样式只作用于当前组件 */</span><br><span class="line">&lt;/style&gt;</span><br></pre></td></tr></table></div></figure><p><strong>作用：</strong></p><ul><li>防止样式污染全局</li><li>自动为选择器添加唯一属性标识</li></ul>        <h4 id="5-2-条件样式类"   >          <a href="#5-2-条件样式类" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-2-条件样式类" class="headerlink" title="5.2 条件样式类"></a>5.2 条件样式类</h4>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">.completed &#123;</span><br><span class="line">  text-decoration: line-through;</span><br><span class="line">  opacity: 0.4;</span><br><span class="line">&#125;</span><br><span class="line">.item &#123;</span><br><span class="line">  /* 正常状态的样式 */</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p><strong>视觉效果：</strong></p><ul><li>已完成事项有删除线且半透明</li><li>通过动态类名绑定实现状态切换</li></ul>        <h3 id="6-响应式系统工作原理"   >          <a href="#6-响应式系统工作原理" class="heading-link"><i class="fas fa-link"></i></a><a href="#6-响应式系统工作原理" class="headerlink" title="6. 响应式系统工作原理"></a>6. 响应式系统工作原理</h3>              <h4 id="6-1-数据变化检测"   >          <a href="#6-1-数据变化检测" class="heading-link"><i class="fas fa-link"></i></a><a href="#6-1-数据变化检测" class="headerlink" title="6.1 数据变化检测"></a>6.1 数据变化检测</h4>      <ul><li>Vue使用Proxy代理监听数据变化</li><li>当 <code>list.value</code>或其中对象属性变化时，触发重新渲染</li></ul>        <h4 id="6-2-虚拟DOM更新"   >          <a href="#6-2-虚拟DOM更新" class="heading-link"><i class="fas fa-link"></i></a><a href="#6-2-虚拟DOM更新" class="headerlink" title="6.2 虚拟DOM更新"></a>6.2 虚拟DOM更新</h4>      <ol><li>数据变化时，Vue生成新的虚拟DOM</li><li>与旧虚拟DOM对比差异（diff算法）</li><li>只更新实际变化的DOM元素，提高性能</li></ol>        <h3 id="7-核心概念总结"   >          <a href="#7-核心概念总结" class="heading-link"><i class="fas fa-link"></i></a><a href="#7-核心概念总结" class="headerlink" title="7. 核心概念总结"></a>7. 核心概念总结</h3>      <div class="table-container"><table><thead><tr><th>概念</th><th>作用</th><th>示例</th></tr></thead><tbody><tr><td><code>ref()</code></td><td>创建响应式数据</td><td><code>const value = ref(&#39;&#39;)</code></td></tr><tr><td><code>v-model</code></td><td>双向数据绑定</td><td><code>&lt;input v-model=&quot;value&quot;&gt;</code></td></tr><tr><td><code>v-for</code></td><td>列表渲染</td><td><code>&lt;div v-for=&quot;item in list&quot;&gt;</code></td></tr><tr><td><code>:class</code></td><td>动态类名</td><td><code>:class=&quot;&#123;completed: item.isCompleted&#125;&quot;</code></td></tr><tr><td><code>@click</code></td><td>事件绑定</td><td><code>@click=&quot;add&quot;</code></td></tr><tr><td><code>methods</code></td><td>定义方法</td><td><code>function add() &#123; ... &#125;</code></td></tr></tbody></table></div><p>这份笔记应该能帮助你理解Vue的核心概念。Vue的设计理念就是”数据驱动视图”，你只需要关注数据的变化，Vue会自动处理视图的更新。</p>        <h2 id="功能需求分解"   >          <a href="#功能需求分解" class="heading-link"><i class="fas fa-link"></i></a><a href="#功能需求分解" class="headerlink" title="功能需求分解"></a>功能需求分解</h2>              <h3 id="1-显示待办列表功能"   >          <a href="#1-显示待办列表功能" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-显示待办列表功能" class="headerlink" title="1. 显示待办列表功能"></a>1. 显示待办列表功能</h3>              <h4 id="数据结构设计"   >          <a href="#数据结构设计" class="heading-link"><i class="fas fa-link"></i></a><a href="#数据结构设计" class="headerlink" title="数据结构设计"></a>数据结构设计</h4>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">const list = ref([</span><br><span class="line">  &#123; value: &#x27;吃饭&#x27;, isCompleted: true &#125;,</span><br><span class="line">  &#123; value: &#x27;睡觉&#x27;, isCompleted: false &#125;,</span><br><span class="line">  &#123; value: &#x27;打豆豆&#x27;, isCompleted: false &#125;,</span><br><span class="line">])</span><br></pre></td></tr></table></div></figure>        <h4 id="实现方式"   >          <a href="#实现方式" class="heading-link"><i class="fas fa-link"></i></a><a href="#实现方式" class="headerlink" title="实现方式"></a>实现方式</h4>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;div v-for=&quot;(item, index) in list&quot; :key=&quot;index&quot;&gt;</span><br><span class="line">  &lt;span&gt;&#123;&#123; item.value &#125;&#125;&lt;/span&gt;</span><br><span class="line">&lt;/div&gt;</span><br></pre></td></tr></table></div></figure><p><strong>原理</strong>：<code>v-for</code>循环遍历数组，为每个事项创建对应的DOM元素</p><hr>        <h3 id="2-添加新事项功能"   >          <a href="#2-添加新事项功能" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-添加新事项功能" class="headerlink" title="2. 添加新事项功能"></a>2. 添加新事项功能</h3>              <h4 id="实现代码"   >          <a href="#实现代码" class="heading-link"><i class="fas fa-link"></i></a><a href="#实现代码" class="headerlink" title="实现代码"></a>实现代码</h4>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">const value = ref(&#x27;&#x27;) // 输入框绑定值</span><br><span class="line"></span><br><span class="line">function add() &#123;</span><br><span class="line">  list.value.push(&#123;</span><br><span class="line">    value: value.value,      // 获取输入框内容</span><br><span class="line">    isCompleted: false,     // 新事项默认未完成</span><br><span class="line">  &#125;)</span><br><span class="line">  value.value = &#x27;&#x27;          // 清空输入框</span><br><span class="line">&#125;</span><br><span class="line">&lt;input v-model=&quot;value&quot; placeholder=&quot;Add a todo&quot;&gt;</span><br><span class="line">&lt;div @click=&quot;add&quot; class=&quot;todo-button&quot;&gt;Add Todo&lt;/div&gt;</span><br></pre></td></tr></table></div></figure>        <h4 id="执行流程："   >          <a href="#执行流程：" class="heading-link"><i class="fas fa-link"></i></a><a href="#执行流程：" class="headerlink" title="执行流程："></a><strong>执行流程</strong>：</h4>      <ol><li>用户在输入框打字 → <code>v-model</code>同步到<code>value</code>变量</li><li>点击按钮 → 触发<code>add</code>函数</li><li>向<code>list</code>数组添加新对象</li><li>清空输入框，准备下一次输入</li></ol><hr>        <h3 id="3-标记完成状态功能"   >          <a href="#3-标记完成状态功能" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-标记完成状态功能" class="headerlink" title="3. 标记完成状态功能"></a>3. 标记完成状态功能</h3>              <h4 id="样式定义"   >          <a href="#样式定义" class="heading-link"><i class="fas fa-link"></i></a><a href="#样式定义" class="headerlink" title="样式定义"></a>样式定义</h4>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">.completed &#123;</span><br><span class="line">  text-decoration: line-through;  /* 删除线 */</span><br><span class="line">  opacity: 0.4;                   /* 半透明 */</span><br><span class="line">&#125;</span><br><span class="line">.item &#123;</span><br><span class="line">  /* 正常状态样式 */</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h4 id="实现方式-1"   >          <a href="#实现方式-1" class="heading-link"><i class="fas fa-link"></i></a><a href="#实现方式-1" class="headerlink" title="实现方式"></a>实现方式</h4>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&lt;div :class=&quot;[item.isCompleted ? &#x27;completed&#x27; : &#x27;item&#x27;]&quot;&gt;</span><br><span class="line">  &lt;input v-model=&quot;item.isCompleted&quot; type=&quot;checkbox&quot;&gt;</span><br><span class="line">  &lt;span class=&quot;name&quot;&gt;&#123;&#123; item.value &#125;&#125;&lt;/span&gt;</span><br><span class="line">&lt;/div&gt;</span><br></pre></td></tr></table></div></figure><p><strong>工作原理</strong>：</p><ul><li><code>v-model=&quot;item.isCompleted&quot;</code>：复选框与完成状态双向绑定</li><li><code>:class</code>动态类名：根据<code>isCompleted</code>值切换样式类</li><li>用户点击复选框 → <code>isCompleted</code>值变化 → 类名自动更新 → 样式生效</li></ul><hr>        <h3 id="4-删除事项功能"   >          <a href="#4-删除事项功能" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-删除事项功能" class="headerlink" title="4. 删除事项功能"></a>4. 删除事项功能</h3>              <h4 id="实现代码-1"   >          <a href="#实现代码-1" class="heading-link"><i class="fas fa-link"></i></a><a href="#实现代码-1" class="headerlink" title="实现代码"></a>实现代码</h4>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">function del(index) &#123;</span><br><span class="line">  list.value.splice(index, 1)  // 从指定位置删除1个元素</span><br><span class="line">&#125;</span><br><span class="line">&lt;div @click=&quot;del(index)&quot; class=&quot;del&quot;&gt;del&lt;/div&gt;</span><br></pre></td></tr></table></div></figure><p><strong>删除逻辑</strong>：</p><ol><li><code>v-for</code>循环时获取每个事项的<code>index</code>（位置索引）</li><li>点击del按钮 → 传入当前项的<code>index</code></li><li><code>splice(index, 1)</code>从数组中删除该位置元素</li><li>Vue自动重新渲染列表</li></ol><p>完整代码</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br></pre></td><td class="code"><pre><span class="line">&lt;script setup&gt;</span><br><span class="line">// 导入Vue的ref函数，用于创建响应式数据</span><br><span class="line">import &#123; ref &#125; from &#x27;vue&#x27;</span><br><span class="line"></span><br><span class="line">// 定义响应式数据</span><br><span class="line">const value = ref(&#x27;&#x27;) // 绑定输入框的值</span><br><span class="line">const list = ref([</span><br><span class="line">  &#123; value: &#x27;吃饭&#x27;, isCompleted: true &#125;,   // 待办事项对象：value-内容，isCompleted-完成状态</span><br><span class="line">  &#123; value: &#x27;睡觉&#x27;, isCompleted: false &#125;,</span><br><span class="line">  &#123; value: &#x27;打豆豆&#x27;, isCompleted: false &#125;,</span><br><span class="line">])</span><br><span class="line"></span><br><span class="line">// 添加待办事项的函数</span><br><span class="line">function add() &#123;</span><br><span class="line">  // 向列表中添加新事项</span><br><span class="line">  list.value.push(&#123;</span><br><span class="line">    value: value.value,        // 使用输入框的当前值</span><br><span class="line">    isCompleted: false,       // 新事项默认未完成</span><br><span class="line">  &#125;)</span><br><span class="line"></span><br><span class="line">  value.value = &#x27;&#x27; // 添加后清空输入框</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">// 删除待办事项的函数</span><br><span class="line">function del(index) &#123;</span><br><span class="line">  // 根据索引从列表中删除对应事项</span><br><span class="line">  list.value.splice(index, 1) // splice(位置, 删除数量)</span><br><span class="line">&#125;</span><br><span class="line">&lt;/script&gt;</span><br><span class="line"></span><br><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;!-- 主容器 --&gt;</span><br><span class="line">  &lt;div class=&quot;todo-app&quot;&gt;</span><br><span class="line">    &lt;!-- 标题 --&gt;</span><br><span class="line">    &lt;div class=&quot;title&quot;&gt;Todo App&lt;/div&gt;</span><br><span class="line"></span><br><span class="line">    &lt;!-- 输入区域 --&gt;</span><br><span class="line">    &lt;div class=&quot;todo-form&quot;&gt;</span><br><span class="line">      &lt;!-- 输入框：v-model实现双向数据绑定 --&gt;</span><br><span class="line">      &lt;input</span><br><span class="line">        v-model=&quot;value&quot;</span><br><span class="line">        type=&quot;text&quot;</span><br><span class="line">        class=&quot;todo-input&quot;</span><br><span class="line">        placeholder=&quot;Add a todo&quot;</span><br><span class="line">      /&gt;</span><br><span class="line">      &lt;!-- 添加按钮：点击触发add函数 --&gt;</span><br><span class="line">      &lt;div @click=&quot;add&quot; class=&quot;todo-button&quot;&gt;Add Todo&lt;/div&gt;</span><br><span class="line">    &lt;/div&gt;</span><br><span class="line"></span><br><span class="line">    &lt;!-- 待办事项列表 --&gt;</span><br><span class="line">    &lt;!-- v-for循环渲染列表，:key提供唯一标识 --&gt;</span><br><span class="line">    &lt;div</span><br><span class="line">      v-for=&quot;(item, index) in list&quot;</span><br><span class="line">      :key=&quot;index&quot;</span><br><span class="line">      &lt;!-- 动态类名：根据完成状态切换样式 --&gt;</span><br><span class="line">      :class=&quot;[item.isCompleted ? &#x27;completed&#x27; : &#x27;item&#x27;]&quot;</span><br><span class="line">    &gt;</span><br><span class="line">      &lt;div&gt;</span><br><span class="line">        &lt;!-- 复选框：绑定完成状态，点击切换isCompleted --&gt;</span><br><span class="line">        &lt;input v-model=&quot;item.isCompleted&quot; type=&quot;checkbox&quot; /&gt;</span><br><span class="line">        &lt;!-- 显示待办内容 --&gt;</span><br><span class="line">        &lt;span class=&quot;name&quot;&gt;&#123;&#123; item.value &#125;&#125;&lt;/span&gt;</span><br><span class="line">      &lt;/div&gt;</span><br><span class="line"></span><br><span class="line">      &lt;!-- 删除按钮：点击时传入当前索引，触发del函数 --&gt;</span><br><span class="line">      &lt;div @click=&quot;del(index)&quot; class=&quot;del&quot;&gt;del&lt;/div&gt;</span><br><span class="line">    &lt;/div&gt;</span><br><span class="line">  &lt;/div&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;style scoped&gt;</span><br><span class="line">/* scoped：样式只作用于当前组件，避免全局污染 */</span><br><span class="line"></span><br><span class="line">/* 主容器样式 */</span><br><span class="line">.todo-app &#123;</span><br><span class="line">  box-sizing: border-box;     /* 盒模型：宽度包含padding和border */</span><br><span class="line">  margin-top: 40px;</span><br><span class="line">  margin-left: 1%;</span><br><span class="line">  padding-top: 30px;</span><br><span class="line">  width: 98%;</span><br><span class="line">  height: 500px;</span><br><span class="line">  background: #ffffff;</span><br><span class="line">  border-radius: 5px;         /* 圆角边框 */</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/* 标题样式 */</span><br><span class="line">.title &#123;</span><br><span class="line">  text-align: center;</span><br><span class="line">  font-size: 30px;</span><br><span class="line">  font-weight: 700;           /* 字体粗细 */</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/* 输入表单布局 */</span><br><span class="line">.todo-form &#123;</span><br><span class="line">  display: flex;              /* 弹性布局，子元素横向排列 */</span><br><span class="line">  margin: 20px 0 30px 20px;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/* 添加按钮样式 */</span><br><span class="line">.todo-button &#123;</span><br><span class="line">  width: 100px;</span><br><span class="line">  height: 52px;</span><br><span class="line">  border-radius: 0 20px 20px 0; /* 右上和右下圆角 */</span><br><span class="line">  text-align: center;</span><br><span class="line">  /* 渐变背景色 */</span><br><span class="line">  background: linear-gradient(</span><br><span class="line">    to right,</span><br><span class="line">    rgb(61, 227, 141),</span><br><span class="line">    rgb(100, 180, 233)</span><br><span class="line">  );</span><br><span class="line">  color: #fff;</span><br><span class="line">  line-height: 52px;          /* 行高实现垂直居中 */</span><br><span class="line">  cursor: pointer;            /* 鼠标悬停时显示手型 */</span><br><span class="line">  font-size: 14px;</span><br><span class="line">  user-select: none;          /* 禁止文字选中 */</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/* 输入框样式 */</span><br><span class="line">.todo-input &#123;</span><br><span class="line">  padding: 0px 15px 0px 15px;</span><br><span class="line">  border-radius: 20px 0 0 20px; /* 左上和左下圆角 */</span><br><span class="line">  border: 1px solid #40d17d;</span><br><span class="line">  outline: none;              /* 移除焦点轮廓 */</span><br><span class="line">  width: 60%;</span><br><span class="line">  height: 50px;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/* 未完成事项的样式 */</span><br><span class="line">.item &#123;</span><br><span class="line">  box-sizing: border-box;</span><br><span class="line">  display: flex;</span><br><span class="line">  align-items: center;        /* 垂直居中 */</span><br><span class="line">  justify-content: space-between; /* 两端对齐 */</span><br><span class="line">  width: 80%;</span><br><span class="line">  height: 50px;</span><br><span class="line">  margin: 8px auto;           /* 上下边距8px，左右自动居中 */</span><br><span class="line">  padding: 16px;</span><br><span class="line">  border-radius: 20px;</span><br><span class="line">  /* 阴影效果 */</span><br><span class="line">  box-shadow: rgba(35, 234, 227, 0.2) 0px 8px 20px;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/* 删除按钮文字颜色 */</span><br><span class="line">.del &#123;</span><br><span class="line">  color: rgb(224, 136, 154);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/* 已完成事项的特殊样式 */</span><br><span class="line">.completed &#123;</span><br><span class="line">  /* 复用item的基本布局样式 */</span><br><span class="line">  box-sizing: border-box;</span><br><span class="line">  display: flex;</span><br><span class="line">  align-items: center;</span><br><span class="line">  justify-content: space-between;</span><br><span class="line">  width: 80%;</span><br><span class="line">  height: 50px;</span><br><span class="line">  margin: 8px auto;</span><br><span class="line">  padding: 16px;</span><br><span class="line">  border-radius: 20px;</span><br><span class="line">  box-shadow: rgba(35, 234, 227, 0.2) 0px 8px 20px;</span><br><span class="line">  </span><br><span class="line">  /* 完成状态特有样式 */</span><br><span class="line">  text-decoration: line-through; /* 删除线效果 */</span><br><span class="line">  opacity: 0.4;                 /* 半透明 */</span><br><span class="line">&#125;</span><br><span class="line">&lt;/style&gt;</span><br></pre></td></tr></table></div></figure>]]></content>
      
      
      <categories>
          
          <category> 前端 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 前端 </tag>
            
            <tag> CSS </tag>
            
            <tag> html </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>模拟</title>
      <link href="/2025/11/11/%E6%A8%A1%E6%8B%9F/"/>
      <url>/2025/11/11/%E6%A8%A1%E6%8B%9F/</url>
      
        <content type="html"><![CDATA[<p>本文收录模拟题</p>        <h1 id="你的牌太多了"   >          <a href="#你的牌太多了" class="heading-link"><i class="fas fa-link"></i></a><a href="#你的牌太多了" class="headerlink" title="你的牌太多了"></a>你的牌太多了</h1>      <p><span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/B3767" >B3767语言月赛202305 你的牌太多了2</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>        <h2 id="题意简介"   >          <a href="#题意简介" class="heading-link"><i class="fas fa-link"></i></a><a href="#题意简介" class="headerlink" title="题意简介"></a>题意简介</h2>      <ul><li><strong>双方</strong>：扶苏(FS) 和 小F(FR)，每人初始n张牌</li><li><strong>牌属性</strong>：每张牌有花色(f)和点数(p)</li><li><strong>目标</strong>：谁先打完所有牌谁获胜（s为1则扶苏先手，2为小F先手）</li></ul>        <h3 id="一轮游戏的流程"   >          <a href="#一轮游戏的流程" class="heading-link"><i class="fas fa-link"></i></a><a href="#一轮游戏的流程" class="headerlink" title="一轮游戏的流程"></a>一轮游戏的流程</h3>              <h4 id="1-首牌规则"   >          <a href="#1-首牌规则" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-首牌规则" class="headerlink" title="1. 首牌规则"></a>1. <strong>首牌规则</strong></h4>      <ul><li>当前轮先手玩家出<strong>点数最小</strong>的牌</li><li>如有多张点数最小，出<strong>花色最小</strong>的那张</li></ul>        <h4 id="2-压制规则"   >          <a href="#2-压制规则" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-压制规则" class="headerlink" title="2. 压制规则"></a>2. <strong>压制规则</strong></h4>      <ul><li>对方必须出<strong>同花色</strong>且<strong>点数更大</strong>的牌来压制</li><li>压制成功则交换出牌权，继续压制</li><li>压制失败则本轮结束</li></ul>        <h4 id="3-轮次交接"   >          <a href="#3-轮次交接" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-轮次交接" class="headerlink" title="3. 轮次交接"></a>3. <strong>轮次交接</strong></h4>      <ul><li>压制失败后，<strong>最后成功出牌者</strong>获得下轮先手权</li><li>游戏持续直到一方牌打完</li></ul>        <h2 id="读题"   >          <a href="#读题" class="heading-link"><i class="fas fa-link"></i></a><a href="#读题" class="headerlink" title="读题"></a>读题</h2>      <p>注意（题意已经有一轮的定义，下文提到的一回合是指一个人出牌另一个选牌（不一定能选到出出去）。所以一轮可能有很多回合。）</p><p>如果你有充足的模拟经验，你就知道<strong>首先确定什么时候结束是一个好习惯</strong>。就像写dfs也会先写好什么时候退出搜索。那么很显然，只要一个人牌数为0就提出。我用num1和num2分别记录牌数。每次出一张牌就num–。我们把模拟过程写到函数里面，用返回值1代表扶苏先出完，2代表f先出完。框架如下</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">play</span><span class="params">(card a[],card b[],<span class="type">int</span> n)</span></span>&#123;</span><br><span class="line">    <span class="type">int</span> num1=n,num2=n;</span><br><span class="line">    <span class="keyword">while</span>(num1&gt;<span class="number">0</span> &amp;&amp; num2&gt;<span class="number">0</span>)&#123;</span><br><span class="line">        <span class="comment">//待补充内容</span></span><br><span class="line">    <span class="keyword">if</span>(num1==<span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(num2==<span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">2</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></div></figure><p>每张牌有花色和点数之分，又因为点数和花色还有优先性，自然想到结构体以及结构体排序</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">struct</span> <span class="title class_">card</span>&#123;</span><br><span class="line">    <span class="type">int</span> num;<span class="comment">//点数</span></span><br><span class="line">    <span class="type">int</span> flo;<span class="comment">//花色</span></span><br><span class="line">&#125;a[<span class="number">105</span>],b[<span class="number">105</span>];<span class="comment">//两个人的手牌</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">bool</span> <span class="title">cmp</span><span class="params">(card a,card b)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(a.num != b.num) <span class="keyword">return</span> a.num &lt; b.num;<span class="comment">//优先点数最小</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">return</span> a.flo &lt; b.flo;<span class="comment">//如有多张点数最小，出花色最小的那张</span></span><br><span class="line">&#125;</span><br><span class="line"> <span class="comment">//sort(a, a + n, cmp);，排序是必要的，但是放在main里面</span></span><br><span class="line"> <span class="comment">//sort(b, b + n, cmp);</span></span><br></pre></td></tr></table></div></figure><p>由于s不同有先后手之分，但是不难想象到这是对称的，也就是说，只要你把一个人先手的情况写好，就可以用cv大法（复制粘贴），然后略微改动就好。框架如下</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span>(s==<span class="number">1</span>)&#123;</span><br><span class="line">    </span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span>&#123;</span><br><span class="line">    </span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>这里我们只分析s&#x3D;&#x3D;1的情况。当扶苏先手，该怎样完成这个模拟。</p><p>因为扶苏先手，所以我需要在a数组中先选一张牌，选点数最小的那张。当然这时候有一个问题，既然我已经排序好了，是不是意味着我直接每次粗暴的选下一个就行，第一次选a[1],第二次a[2]……显然不对，因为有的牌不一定符合规则，如果到后面牌权交换，你要压制对方的话，可能你现下的牌不满足需求，就会跳。所以我们用一个vis[]数组标记双方的牌有没有出过。</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">bool</span> vis1[<span class="number">105</span>],vis2[<span class="number">105</span>];</span><br></pre></td></tr></table></div></figure><p>所以后面选牌时我们加上一个vis判断即可。</p><p>当扶苏选出了自己的第一张牌，那么小F就要压制他了。压制的规则是，花色相同且点数大于对方。很好实现。那么我只要比较扶苏和f出的牌就好了。但是问题来了，我该怎么记录扶苏出的牌。这么写是对的吗？</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">0</span>;i&lt;n;i++)&#123;</span><br><span class="line">     <span class="keyword">if</span>(vis1[i]==<span class="number">1</span>) <span class="keyword">continue</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> j=<span class="number">0</span>;j&lt;n;j++)&#123;</span><br><span class="line">        <span class="keyword">if</span>(vis2[i]==<span class="number">1</span>)<span class="keyword">continue</span>;</span><br><span class="line">        <span class="keyword">if</span>(a[i].flo==b[j].flo &amp;&amp; a[i].num&lt;b[j].num)&#123;</span><br><span class="line">              a[i].num = <span class="number">0</span>;</span><br><span class="line">              b[j].num = <span class="number">0</span>;         </span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>这样写是不满足题意的回合制的。你要知道，牌权并不是你出完到我。而是，一轮游戏（除第一轮先手确定）的先手是上一轮出牌的最后一个人。也就是说要是小F无法压制，那本轮结束，下一轮还是扶苏先手。如果可以压制，那扶苏需要看能不能有牌压制小F用来压制的牌，然后一直进行，直到有一方无法出牌。<strong>这里你要敏锐的感知到</strong>，<strong>每轮游戏的回合是不固定的</strong>，而且每一回合的出牌人也不固定。所以需要一个while(1)循环，直到不满足条件退出循环。</p><p>回到刚刚的问题，如何记录扶苏出的牌，来确保回合制可以进行。其实我只要把选牌这个阶段单独拎出来，**然后再用一个结构体数组tmp记录当下选的是什么牌，**把对方的压制写到后面就好。同时确保这个牌没被用过。（不要忘记每次出牌num都–）</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i++)&#123;</span><br><span class="line">    <span class="keyword">if</span>(vis1[i] == <span class="number">0</span>)&#123;</span><br><span class="line">           tmp = a[i];</span><br><span class="line">           num1--;</span><br><span class="line">            vis1[i] = <span class="number">1</span>;</span><br><span class="line">             <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br></pre></td></tr></table></div></figure><p>现在扶苏选出来他先手要出的牌，要轮到f来选牌压制了。那么我们用循环来找，<strong>如果找到了符合条件的，就说明压制成功了。没用找到的话，压制失败本轮结束，由扶苏继续出牌</strong>。</p><p>也就是说，轮到小f出牌的回合会有两个结果，（压制成功和压制失败）。**那么我们用一个变量bool found&#x3D;false来判断。**如果找到了，found&#x3D;true,否则就本轮结束。</p><p>代码写到这步，你就要意识到这是你改写while(1)的时候了。因为你的轮数开始不确定了。</p><p>而因为一轮的各个回合中，不一定谁能最终压制成功，所以有两个点是不确定的。</p><ul><li>谁是下一轮的先手 用next表示</li><li>当前轮次谁下一个出牌（谁要进行压制） 用now表示</li></ul><p>每一次出牌，我设置变量next，表示本轮结束后下一轮先手。仍然next&#x3D;&#x3D;1表示扶苏，2表示f。</p><p>用now变量表示下一个是谁出牌。now&#x3D;&#x3D;1是表示扶苏，2表示f。</p><p>这个now好说，假设轮到f进行压制时，如果压制成功，本轮继续，就轮到扶苏出牌。now从2变1。如果压制失败，found&#x3D;false，进入下一轮。这时now不变，还是2。因为上一轮最后出牌的是f。综上来说，只要轮到谁时谁成功压制，now就轮到对方，否则保持。</p><p>而next呢，谁是下一回合的先手，是不是由这一轮是谁最后出牌来表示。谁压制成功，谁就可能是这一轮最后的最后一个。也就是说，如果now&#x3D;&#x3D;2，就说明现在f要进行压制，如果压制成功，next也应该等于2。</p><p>好的，不知道多少回合后，假设一轮已经结束，扶苏没能压制成功对方，那新的一轮中，是不是小f就要选牌了。那现在就是相当于小f先手。如何模拟这个控制呢？</p><p>我们前面已经提到用next表示谁是下一轮的先手。所以只要每次一轮过后，压制成功时，让first等于next。first为1时选扶苏的牌，否则f。</p><p>现在我们来汇总前面代码框架。</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">while</span>(num1&gt;<span class="number">0</span> &amp;&amp; num2&gt;<span class="number">0</span>)&#123;</span><br><span class="line">    <span class="keyword">if</span>(first==<span class="number">1</span>)&#123;<span class="comment">//本轮从扶苏开始</span></span><br><span class="line">        <span class="comment">//扶苏开始选牌</span></span><br><span class="line">        <span class="comment">//开始本轮循环</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span>&#123;<span class="comment">//本轮从f开始</span></span><br><span class="line">        <span class="comment">//f开始选牌</span></span><br><span class="line">        <span class="comment">//开始本轮循环</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(num1==<span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(num2==<span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">2</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>现在我们补充好first&#x3D;&#x3D;1时的代码</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span>(first==<span class="number">1</span>)&#123;</span><br><span class="line">    card tmp;<span class="comment">//记录当前出的牌</span></span><br><span class="line">    <span class="type">int</span> next=<span class="number">1</span>;<span class="comment">//next初始化，下一轮出牌人</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">//扶苏选牌</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">0</span>;i&lt;n;i++)&#123;</span><br><span class="line">        <span class="keyword">if</span>(vis[i]==<span class="number">0</span>)&#123;</span><br><span class="line">            tmp==a[i];</span><br><span class="line">            num1--;</span><br><span class="line">            vis1[i]=<span class="number">1</span>;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="type">int</span> now=<span class="number">2</span>;<span class="comment">//当前轮下一个出牌的人，初始化</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">//开始互相压制的多个回合</span></span><br><span class="line">    <span class="keyword">while</span>(<span class="number">1</span>)&#123;</span><br><span class="line">      <span class="type">bool</span> found=<span class="literal">false</span>;<span class="comment">//标记是否成功压制</span></span><br><span class="line">        </span><br><span class="line">        <span class="comment">//轮到f压制</span></span><br><span class="line">      <span class="keyword">if</span>(now==<span class="number">2</span>)&#123;</span><br><span class="line">          <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">0</span>;i&lt;n;i++)&#123;</span><br><span class="line">              <span class="keyword">if</span>(vis[i]==<span class="number">0</span> &amp;&amp; b[i].flo==tmp.flo &amp;&amp; b[i].num &gt;tmp.num)&#123;</span><br><span class="line">                  found=<span class="literal">true</span>;<span class="comment">//已经找到符合要求的牌，压制成功</span></span><br><span class="line">                  tmp=b[i];<span class="comment">//当前牌变为f用来压制的牌</span></span><br><span class="line">                  num2--;<span class="comment">//打出一张</span></span><br><span class="line">                  vis2[i]=<span class="number">1</span>;<span class="comment">//这张牌已经用过了</span></span><br><span class="line">                  now=<span class="number">1</span>;<span class="comment">//压制成功后轮到扶苏出牌了</span></span><br><span class="line">                  next=<span class="number">2</span>;<span class="comment">//如果扶苏没能压制成功更改next变量，下一轮就是f出牌</span></span><br><span class="line">                  <span class="keyword">break</span>;<span class="comment">//找到牌打出，结束f这次出牌</span></span><br><span class="line">              &#125;</span><br><span class="line">          &#125;</span><br><span class="line">      &#125;</span><br><span class="line">        </span><br><span class="line">       <span class="comment">//轮到扶苏压制</span></span><br><span class="line">      <span class="keyword">else</span>&#123;</span><br><span class="line">          <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">0</span>;i&lt;n;i++)&#123;</span><br><span class="line">     <span class="keyword">if</span>(vis1[i] == <span class="number">0</span> &amp;&amp; a[i].flo == tmp.flo &amp;&amp; a[i].num &gt; tmp.num)&#123;</span><br><span class="line">                found=<span class="literal">true</span>;</span><br><span class="line">                tmp=a[i];</span><br><span class="line">                num1--;</span><br><span class="line">                vis1[i]=<span class="number">1</span>;</span><br><span class="line">                now=<span class="number">2</span>;</span><br><span class="line">                next=<span class="number">1</span>;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">          &#125;</span><br><span class="line">      &#125;</span><br><span class="line">        <span class="keyword">if</span>(!found) <span class="keyword">break</span>;<span class="comment">//没压制成功的话，本轮直接结束进入下一回合</span></span><br><span class="line">        </span><br><span class="line">    &#125;</span><br><span class="line">    first=next;<span class="comment">//压制成功了，这一轮出牌的最后一个人，变成下一轮的先手，要先选牌</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>终于吃完了这坨史，附上ac代码美美下班。</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">card</span>&#123;</span><br><span class="line">    <span class="type">int</span> num;</span><br><span class="line">    <span class="type">int</span> flo;</span><br><span class="line">&#125;a[<span class="number">105</span>],b[<span class="number">105</span>];</span><br><span class="line"></span><br><span class="line"><span class="type">bool</span> vis1[<span class="number">105</span>],vis2[<span class="number">105</span>];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">bool</span> <span class="title">cmp</span><span class="params">(card a,card b)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(a.num != b.num) <span class="keyword">return</span> a.num &lt; b.num;</span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">return</span> a.flo &lt; b.flo;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">play</span><span class="params">(card a[],card b[],<span class="type">int</span> n)</span></span>&#123;</span><br><span class="line">    <span class="built_in">memset</span>(vis1, <span class="number">0</span>, <span class="built_in">sizeof</span>(vis1));</span><br><span class="line">    <span class="built_in">memset</span>(vis2, <span class="number">0</span>, <span class="built_in">sizeof</span>(vis2));</span><br><span class="line">    <span class="type">int</span> num1 = n, num2 = n;</span><br><span class="line">    <span class="type">int</span> first = <span class="number">1</span>;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">while</span>(num1 &gt; <span class="number">0</span> &amp;&amp; num2 &gt; <span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">if</span>(first == <span class="number">1</span>)&#123;</span><br><span class="line">            card tmp;</span><br><span class="line">            <span class="type">int</span> next = <span class="number">1</span>;</span><br><span class="line">            <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i++)&#123;</span><br><span class="line">                <span class="keyword">if</span>(vis1[i] == <span class="number">0</span>)&#123;</span><br><span class="line">                    tmp = a[i];</span><br><span class="line">                    num1--;</span><br><span class="line">                    vis1[i] = <span class="number">1</span>;</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="type">int</span> now = <span class="number">2</span>;</span><br><span class="line">            <span class="keyword">while</span>(<span class="number">1</span>)&#123;</span><br><span class="line">                <span class="type">bool</span> found = <span class="literal">false</span>;</span><br><span class="line">                <span class="keyword">if</span>(now == <span class="number">2</span>)&#123;</span><br><span class="line">                    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i++)&#123;</span><br><span class="line">                        <span class="keyword">if</span>(vis2[i] == <span class="number">0</span> &amp;&amp; b[i].flo == tmp.flo &amp;&amp; b[i].num &gt; tmp.num)&#123;</span><br><span class="line">                            found = <span class="literal">true</span>;</span><br><span class="line">                            tmp = b[i];</span><br><span class="line">                            num2--;</span><br><span class="line">                            vis2[i] = <span class="number">1</span>;</span><br><span class="line">                            now = <span class="number">1</span>;</span><br><span class="line">                            next = <span class="number">2</span>;</span><br><span class="line">                            <span class="keyword">break</span>;</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">else</span>&#123;</span><br><span class="line">                    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i++)&#123;</span><br><span class="line">                        <span class="keyword">if</span>(vis1[i] == <span class="number">0</span> &amp;&amp; a[i].flo == tmp.flo &amp;&amp; a[i].num &gt; tmp.num)&#123;</span><br><span class="line">                            found = <span class="literal">true</span>;</span><br><span class="line">                            tmp = a[i];</span><br><span class="line">                            num1--;</span><br><span class="line">                            vis1[i] = <span class="number">1</span>;</span><br><span class="line">                            now = <span class="number">2</span>;</span><br><span class="line">                            next = <span class="number">1</span>;</span><br><span class="line">                            <span class="keyword">break</span>;</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span>(!found) <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            first = next;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span>&#123;</span><br><span class="line">            card tmp;</span><br><span class="line">            <span class="type">int</span> next = <span class="number">2</span>;</span><br><span class="line">            <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i++)&#123;</span><br><span class="line">                <span class="keyword">if</span>(vis2[i] == <span class="number">0</span>)&#123;</span><br><span class="line">                    tmp = b[i];</span><br><span class="line">                    num2--;</span><br><span class="line">                    vis2[i] = <span class="number">1</span>;</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="type">int</span> now = <span class="number">1</span>;</span><br><span class="line">            <span class="keyword">while</span>(<span class="number">1</span>)&#123;</span><br><span class="line">                <span class="type">bool</span> found = <span class="literal">false</span>;</span><br><span class="line">                <span class="keyword">if</span>(now == <span class="number">1</span>)&#123;</span><br><span class="line">                    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i++)&#123;</span><br><span class="line">                        <span class="keyword">if</span>(vis1[i] == <span class="number">0</span> &amp;&amp; a[i].flo == tmp.flo &amp;&amp; a[i].num &gt; tmp.num)&#123;</span><br><span class="line">                            found = <span class="literal">true</span>;</span><br><span class="line">                            tmp = a[i];</span><br><span class="line">                            num1--;</span><br><span class="line">                            vis1[i] = <span class="number">1</span>;</span><br><span class="line">                            now = <span class="number">2</span>;</span><br><span class="line">                            next = <span class="number">1</span>;</span><br><span class="line">                            <span class="keyword">break</span>;</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">else</span>&#123;</span><br><span class="line">                    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i++)&#123;</span><br><span class="line">                        <span class="keyword">if</span>(vis2[i] == <span class="number">0</span> &amp;&amp; b[i].flo == tmp.flo &amp;&amp; b[i].num &gt; tmp.num)&#123;</span><br><span class="line">                            found = <span class="literal">true</span>;</span><br><span class="line">                            tmp = b[i];</span><br><span class="line">                            num2--;</span><br><span class="line">                            vis2[i] = <span class="number">1</span>;</span><br><span class="line">                            now = <span class="number">1</span>;</span><br><span class="line">                            next = <span class="number">2</span>;</span><br><span class="line">                            <span class="keyword">break</span>;</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span>(!found) <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            first = next;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">if</span>(num1 == <span class="number">0</span>) <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">return</span> <span class="number">2</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="type">int</span> t;</span><br><span class="line">    cin &gt;&gt; t;</span><br><span class="line">    <span class="keyword">while</span>(t--)&#123;</span><br><span class="line">        <span class="type">int</span> n, m, r, s;</span><br><span class="line">        cin &gt;&gt; n &gt;&gt; m &gt;&gt; r &gt;&gt; s;</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i++) cin &gt;&gt; a[i].flo;</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i++) cin &gt;&gt; a[i].num;</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i++) cin &gt;&gt; b[i].flo;</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i++) cin &gt;&gt; b[i].num;</span><br><span class="line">        </span><br><span class="line">        <span class="built_in">sort</span>(a, a + n, cmp);</span><br><span class="line">        <span class="built_in">sort</span>(b, b + n, cmp);</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">if</span>(s == <span class="number">1</span>)&#123;</span><br><span class="line">            <span class="type">int</span> result = <span class="built_in">play</span>(a, b, n);</span><br><span class="line">            <span class="keyword">if</span>(result == <span class="number">1</span>)&#123;</span><br><span class="line">                cout &lt;&lt; <span class="string">&quot;FS wins!&quot;</span> &lt;&lt; endl;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                cout &lt;&lt; <span class="string">&quot;FR wins!&quot;</span> &lt;&lt; endl;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="type">int</span> result = <span class="built_in">play</span>(b, a, n);</span><br><span class="line">            <span class="keyword">if</span>(result == <span class="number">1</span>)&#123;</span><br><span class="line">                cout &lt;&lt; <span class="string">&quot;FR wins!&quot;</span> &lt;&lt; endl;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                cout &lt;&lt; <span class="string">&quot;FS wins!&quot;</span> &lt;&lt; endl;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="精灵宝可梦对战"   >          <a href="#精灵宝可梦对战" class="heading-link"><i class="fas fa-link"></i></a><a href="#精灵宝可梦对战" class="headerlink" title="精灵宝可梦对战"></a>精灵宝可梦对战</h1>      <p><span class="exturl"><a class="exturl__link"   href="https://codeforces.com/gym/104725/problem/G" >2023ccpc女赛G.精灵宝可梦对战</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>        <h3 id="基本规则"   >          <a href="#基本规则" class="heading-link"><i class="fas fa-link"></i></a><a href="#基本规则" class="headerlink" title="基本规则"></a>基本规则</h3>      <ul><li>小A和小B各有若干宝可梦，每个宝可梦有7种属性</li><li>双方轮流攻击，小A先手</li><li>每轮包括两次攻击：小A攻击 → 小B攻击</li><li>攻击方选择造成伤害最高的技能</li><li>宝可梦轮换机制：攻击后排到队尾，下一只上场</li></ul>        <h3 id="胜负条件"   >          <a href="#胜负条件" class="heading-link"><i class="fas fa-link"></i></a><a href="#胜负条件" class="headerlink" title="胜负条件"></a>胜负条件</h3>      <ul><li><strong>小A胜利</strong>：小B的所有宝可梦HP ≤ 0</li><li><strong>小B胜利</strong>：小A的所有宝可梦HP ≤ 0</li><li><strong>平局</strong>：进行K轮后仍未分出胜负</li></ul><p>代码所述备矣，后面有心情再补充一点题解</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">1e5</span> + <span class="number">5</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 小A的宝可梦属性数组</span></span><br><span class="line"><span class="type">int</span> h1[N]; <span class="comment">// 血量</span></span><br><span class="line"><span class="type">int</span> a1[N]; <span class="comment">// 物理攻击</span></span><br><span class="line"><span class="type">int</span> b1[N]; <span class="comment">// 魔法攻击</span></span><br><span class="line"><span class="type">int</span> c1[N]; <span class="comment">// 物理防御</span></span><br><span class="line"><span class="type">int</span> d1[N]; <span class="comment">// 魔法防御</span></span><br><span class="line"><span class="type">int</span> e1[N]; <span class="comment">// 终极技能所需能量</span></span><br><span class="line"><span class="type">int</span> w1[N]; <span class="comment">// 终极技能伤害</span></span><br><span class="line"><span class="type">int</span> ea[N]; <span class="comment">// 当前能量值</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 小B的宝可梦属性数组（同上）</span></span><br><span class="line"><span class="type">int</span> h2[N], a2[N], b2[N], c2[N], d2[N], e2[N], w2[N], eb[N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 优化输入输出</span></span><br><span class="line">    ios::<span class="built_in">sync_with_stdio</span>(<span class="literal">false</span>);</span><br><span class="line">    cin.<span class="built_in">tie</span>(<span class="number">0</span>);</span><br><span class="line">    cout.<span class="built_in">tie</span>(<span class="number">0</span>);</span><br><span class="line">    </span><br><span class="line">    <span class="type">int</span> n, m, k;</span><br><span class="line">    cin &gt;&gt; n &gt;&gt; m &gt;&gt; k;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 使用队列管理存活的宝可梦</span></span><br><span class="line">    queue&lt;<span class="type">int</span>&gt; A, B;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 读取小A的宝可梦数据</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        cin &gt;&gt; h1[i] &gt;&gt; a1[i] &gt;&gt; b1[i] &gt;&gt; c1[i] &gt;&gt; d1[i] &gt;&gt; e1[i] &gt;&gt; w1[i];</span><br><span class="line">        ea[i] = <span class="number">0</span>; <span class="comment">// 初始化能量为0</span></span><br><span class="line">        A.<span class="built_in">push</span>(i); <span class="comment">// 将宝可梦加入队列</span></span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 读取小B的宝可梦数据</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i &lt;= m; i++) &#123;</span><br><span class="line">        cin &gt;&gt; h2[i] &gt;&gt; a2[i] &gt;&gt; b2[i] &gt;&gt; c2[i] &gt;&gt; d2[i] &gt;&gt; e2[i] &gt;&gt; w2[i];</span><br><span class="line">        eb[i] = <span class="number">0</span>; <span class="comment">// 初始化能量为0</span></span><br><span class="line">        B.<span class="built_in">push</span>(i); <span class="comment">// 将宝可梦加入队列</span></span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="type">int</span> cnt = <span class="number">0</span>; <span class="comment">// 记录当前轮数</span></span><br><span class="line">    <span class="type">int</span> nowa, nowb; <span class="comment">// 当前对战的宝可梦索引</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 战斗主循环</span></span><br><span class="line">    <span class="keyword">while</span>(!A.<span class="built_in">empty</span>() &amp;&amp; !B.<span class="built_in">empty</span>() &amp;&amp; cnt &lt; k) &#123;</span><br><span class="line">        <span class="comment">// 获取当前对战的宝可梦</span></span><br><span class="line">        nowa = A.<span class="built_in">front</span>();</span><br><span class="line">        nowb = B.<span class="built_in">front</span>();</span><br><span class="line">        A.<span class="built_in">pop</span>();</span><br><span class="line">        B.<span class="built_in">pop</span>();</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 小A的宝可梦攻击小B的宝可梦</span></span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 计算三种攻击方式的伤害</span></span><br><span class="line">        <span class="type">int</span> p = <span class="built_in">max</span>(<span class="number">0</span>, a1[nowa] - c2[nowb]); <span class="comment">// 物理攻击伤害</span></span><br><span class="line">        <span class="type">int</span> ma = <span class="built_in">max</span>(<span class="number">0</span>, b1[nowa] - d2[nowb]); <span class="comment">// 魔法攻击伤害</span></span><br><span class="line">        <span class="type">int</span> ww = <span class="number">0</span>; <span class="comment">// 终极技能伤害初始为0</span></span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 检查是否可以释放终极技能</span></span><br><span class="line">        <span class="keyword">if</span>(ea[nowa] &gt;= e1[nowa])</span><br><span class="line">            ww = w1[nowa]; <span class="comment">// 满足条件则设置终极技能伤害</span></span><br><span class="line">            </span><br><span class="line">        <span class="comment">// 选择伤害最大的攻击方式</span></span><br><span class="line">        <span class="type">int</span> hurt = <span class="built_in">max</span>(&#123;p, ma, ww&#125;);</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 应用伤害并更新能量</span></span><br><span class="line">        <span class="keyword">if</span>(p == hurt) &#123; <span class="comment">// 选择物理攻击</span></span><br><span class="line">            ea[nowa]++; <span class="comment">// 物理攻击增加能量</span></span><br><span class="line">            h2[nowb] -= p; <span class="comment">// 造成伤害</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span> <span class="keyword">if</span>(ma == hurt) &#123; <span class="comment">// 选择魔法攻击</span></span><br><span class="line">            ea[nowa]++; <span class="comment">// 魔法攻击增加能量</span></span><br><span class="line">            h2[nowb] -= ma; <span class="comment">// 造成伤害</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span> &#123; <span class="comment">// 选择终极技能</span></span><br><span class="line">            ea[nowa] -= e1[nowa]; <span class="comment">// 消耗能量</span></span><br><span class="line">            h2[nowb] -= ww; <span class="comment">// 造成伤害</span></span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 将攻击方宝可梦放回队列末尾（轮换）</span></span><br><span class="line">        A.<span class="built_in">push</span>(nowa);</span><br><span class="line">        nowa = A.<span class="built_in">front</span>(); <span class="comment">// 获取下一个准备上场的宝可梦</span></span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 检查防御方宝可梦是否阵亡</span></span><br><span class="line">        <span class="keyword">if</span>(h2[nowb] &lt;= <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span>(!B.<span class="built_in">empty</span>()) &#123;</span><br><span class="line">                nowb = B.<span class="built_in">front</span>(); <span class="comment">// 更换下一个宝可梦</span></span><br><span class="line">                B.<span class="built_in">pop</span>();</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> <span class="keyword">break</span>; <span class="comment">// 没有宝可梦可换了，结束战斗</span></span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 小B的宝可梦攻击小A的宝可梦（同上逻辑）</span></span><br><span class="line">        p = <span class="built_in">max</span>(<span class="number">0</span>, a2[nowb] - c1[nowa]); <span class="comment">// 物理攻击伤害</span></span><br><span class="line">        ma = <span class="built_in">max</span>(<span class="number">0</span>, b2[nowb] - d1[nowa]); <span class="comment">// 魔法攻击伤害</span></span><br><span class="line">        ww = <span class="number">0</span>; <span class="comment">// 终极技能伤害初始为0</span></span><br><span class="line">        </span><br><span class="line">        <span class="keyword">if</span>(eb[nowb] &gt;= e2[nowb])</span><br><span class="line">            ww = w2[nowb]; <span class="comment">// 满足条件则设置终极技能伤害</span></span><br><span class="line">            </span><br><span class="line">        hurt = <span class="built_in">max</span>(&#123;p, ma, ww&#125;); <span class="comment">// 选择最大伤害</span></span><br><span class="line">        </span><br><span class="line">        <span class="keyword">if</span>(p == hurt) &#123; <span class="comment">// 物理攻击</span></span><br><span class="line">            eb[nowb]++;</span><br><span class="line">            h1[nowa] -= p;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span> <span class="keyword">if</span>(ma == hurt) &#123; <span class="comment">// 魔法攻击</span></span><br><span class="line">            eb[nowb]++;</span><br><span class="line">            h1[nowa] -= ma;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span> &#123; <span class="comment">// 终极技能</span></span><br><span class="line">            eb[nowb] -= e2[nowb];</span><br><span class="line">            h1[nowa] -= ww;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 将攻击方宝可梦放回队列末尾（轮换）</span></span><br><span class="line">        B.<span class="built_in">push</span>(nowb);</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 检查防御方宝可梦是否阵亡</span></span><br><span class="line">        <span class="keyword">if</span>(h1[nowa] &lt;= <span class="number">0</span>) </span><br><span class="line">            A.<span class="built_in">pop</span>(); <span class="comment">// 阵亡则从队列中移除</span></span><br><span class="line">        </span><br><span class="line">        cnt++; <span class="comment">// 增加轮数</span></span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 输出战斗结果</span></span><br><span class="line">    <span class="keyword">if</span>(!A.<span class="built_in">empty</span>() &amp;&amp; !B.<span class="built_in">empty</span>()) </span><br><span class="line">        cout &lt;&lt; <span class="string">&quot;Draw&quot;</span> &lt;&lt; <span class="string">&#x27;\n&#x27;</span>; <span class="comment">// 双方都有宝可梦存活</span></span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">if</span>(!A.<span class="built_in">empty</span>())</span><br><span class="line">        cout &lt;&lt; <span class="string">&quot;Alice&quot;</span> &lt;&lt; <span class="string">&#x27;\n&#x27;</span>; <span class="comment">// 小A获胜</span></span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">        cout &lt;&lt; <span class="string">&quot;Bob&quot;</span> &lt;&lt; <span class="string">&#x27;\n&#x27;</span>; <span class="comment">// 小B获胜</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="疾羽的救赎"   >          <a href="#疾羽的救赎" class="heading-link"><i class="fas fa-link"></i></a><a href="#疾羽的救赎" class="headerlink" title="疾羽的救赎"></a>疾羽的救赎</h1>      <p><span class="exturl"><a class="exturl__link"   href="https://codeforces.com/gym/104725/problem/A" >2023ccpc女赛A.疾羽的救赎</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>        <h3 id="🧩-核心规则"   >          <a href="#🧩-核心规则" class="heading-link"><i class="fas fa-link"></i></a><a href="#🧩-核心规则" class="headerlink" title="🧩 核心规则"></a>🧩 核心规则</h3>      <p><strong>游戏元素</strong>：三种颜色棋子（紫&#x2F;绿&#x2F;黄）放置在编号2-9的棋盘格上，初始位置分别为格子2、3、4。棋子按<strong>栈结构</strong>叠放，移动时<strong>整体迁移</strong>——移动一个棋子会同时移动其上方所有棋子。</p><p><strong>输入格式</strong>：12张行动卡片，每张包含<code>颜色编号</code>和<code>移动步数</code>。如输入<code>1 3</code>表示移动紫色棋子3步。</p><p><strong>移动机制</strong>：从当前格子<code>now</code>移动到<code>now + b</code>号格子，棋子放置在目标格子栈顶。</p>        <h3 id="🎮-胜负条件"   >          <a href="#🎮-胜负条件" class="heading-link"><i class="fas fa-link"></i></a><a href="#🎮-胜负条件" class="headerlink" title="🎮 胜负条件"></a>🎮 胜负条件</h3>      <p><strong>成功标准</strong>：所有棋子最终都到达9号格子。程序输出<code>&quot;Y&quot;</code>表示成功，<code>&quot;N&quot;</code>表示失败。</p><p>仍然先把代码和注释扔上来。具体的后面补</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="meta">#<span class="keyword">define</span> int long long</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">solve</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">// v[10] 存储每个格子上的棋子栈</span></span><br><span class="line">    <span class="comment">// v[i] 表示第i个格子上叠放的棋子（从下到上的顺序）</span></span><br><span class="line">    vector&lt;<span class="type">int</span>&gt; v[<span class="number">10</span>];  </span><br><span class="line">    </span><br><span class="line">    <span class="comment">// qi[4] 存储每个颜色棋子当前所在的格子编号</span></span><br><span class="line">    <span class="comment">// qi[1] = 紫色棋子位置, qi[2] = 绿色棋子位置, qi[3] = 黄色棋子位置</span></span><br><span class="line">    <span class="function">vector&lt;<span class="type">int</span>&gt; <span class="title">qi</span><span class="params">(<span class="number">4</span>)</span></span>;  </span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 初始化棋盘状态：</span></span><br><span class="line">    <span class="comment">// 2号格子放紫色棋子(编号1)，3号格子放绿色棋子(编号2)，4号格子放黄色棋子(编号3)</span></span><br><span class="line">    v[<span class="number">2</span>].<span class="built_in">push_back</span>(<span class="number">1</span>);</span><br><span class="line">    v[<span class="number">3</span>].<span class="built_in">push_back</span>(<span class="number">2</span>);</span><br><span class="line">    v[<span class="number">4</span>].<span class="built_in">push_back</span>(<span class="number">3</span>);</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 初始化每个颜色棋子的位置跟踪</span></span><br><span class="line">    qi[<span class="number">1</span>] = <span class="number">2</span>;  <span class="comment">// 紫色棋子在2号格子</span></span><br><span class="line">    qi[<span class="number">2</span>] = <span class="number">3</span>;  <span class="comment">// 绿色棋子在3号格子  </span></span><br><span class="line">    qi[<span class="number">3</span>] = <span class="number">4</span>;  <span class="comment">// 黄色棋子在4号格子</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 处理12张行动卡片</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= <span class="number">12</span>; i++) &#123;</span><br><span class="line">        <span class="type">int</span> a, b, pos = <span class="number">-1</span>;</span><br><span class="line">        cin &gt;&gt; a &gt;&gt; b;  <span class="comment">// 输入卡片颜色和步数</span></span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 获取当前颜色棋子所在的格子编号</span></span><br><span class="line">        <span class="type">int</span> now = qi[a];</span><br><span class="line">        <span class="comment">// 计算移动后的目标格子编号</span></span><br><span class="line">        <span class="type">int</span> nex = now + b;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 在当前格子的棋子栈中查找该颜色棋子的位置</span></span><br><span class="line">        <span class="comment">// 因为棋子可能被其他棋子压住，需要找到它在栈中的索引</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">0</span>; j &lt; v[now].<span class="built_in">size</span>(); j++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (v[now][j] == a) &#123;</span><br><span class="line">                pos = j;  <span class="comment">// 记录该棋子及其上方所有棋子的起始位置</span></span><br><span class="line">                <span class="keyword">break</span>;  </span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 将该棋子及其上方的所有棋子移动到新格子</span></span><br><span class="line">        <span class="comment">// 从pos位置开始到栈顶的所有棋子都要移动</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> j = pos; j &lt; v[now].<span class="built_in">size</span>(); j++) &#123;</span><br><span class="line">            <span class="comment">// 更新被移动棋子的位置信息</span></span><br><span class="line">            qi[v[now][j]] = nex;</span><br><span class="line">            <span class="comment">// 将棋子添加到新格子的栈顶</span></span><br><span class="line">            v[nex].<span class="built_in">push_back</span>(v[now][j]);</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 从原格子中移除被移动的棋子</span></span><br><span class="line">        <span class="comment">// 注意：需要先保存原长度，因为pop_back()会改变size()</span></span><br><span class="line">        <span class="type">int</span> len = v[now].<span class="built_in">size</span>();</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> j = pos; j &lt; len; j++) &#123;</span><br><span class="line">            v[now].<span class="built_in">pop_back</span>();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 检查所有棋子是否都在9号格子上</span></span><br><span class="line">    <span class="comment">// 如果9号格子上有3个棋子，说明全部移动成功</span></span><br><span class="line">    cout &lt;&lt; (v[<span class="number">9</span>].<span class="built_in">size</span>() == <span class="number">3</span> ? <span class="string">&quot;Y&quot;</span> : <span class="string">&quot;N&quot;</span>) &lt;&lt; <span class="string">&#x27;\n&#x27;</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">signed</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 优化输入输出速度</span></span><br><span class="line">    ios::<span class="built_in">sync_with_stdio</span>(<span class="number">0</span>), cin.<span class="built_in">tie</span>(<span class="number">0</span>), cout.<span class="built_in">tie</span>(<span class="number">0</span>);</span><br><span class="line">    </span><br><span class="line">    <span class="type">int</span> t = <span class="number">1</span>;</span><br><span class="line">    cin &gt;&gt; t;  <span class="comment">// 读取测试用例数量</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 处理每个测试用例</span></span><br><span class="line">    <span class="keyword">while</span> (t--) &#123;</span><br><span class="line">        <span class="built_in">solve</span>();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="Painter"   >          <a href="#Painter" class="heading-link"><i class="fas fa-link"></i></a><a href="#Painter" class="headerlink" title="Painter"></a>Painter</h1>      <p><span class="exturl"><a class="exturl__link"   href="https://codeforces.com/gym/104813/problem/M" >2023沈阳</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p><p>一道有一点点技术的模拟题目。</p><p>大致题意是，有三种操作，第一种操作给出你圆心和半径以及符号。圆内的点都变这个符号。第二种操作给你矩形，在矩形内的变为这个符号。第三种给你四个数，y1-y1行的x2-x1列，打印出来这个范围对应的符号。</p><p>由于整个图太大，首先排除存下整个图暴力的可能性。那是不是就没用办法了呢？注意它每次只需要输出给出范围的图的符号。所以我们只需要判断这个范围的点有没有被渲染过。</p><p>由于有多次渲染，一次次覆盖显然有些浪费时间。但我们既然都说了是覆盖，那说明一个点，只要被最后一次操作渲染了，前面的就都不用管了。以此类推。所以我们可以一个点一个点的遍历，对于每个点，我们从预先存好的操作数组里面从后向前遍历（看后面的渲染，而不看会被覆盖的）。如果这个点在某次操作成功被渲染，那后面就不用看了，直接break。</p><p>理解完题意和模拟思路，你就要知道代码该怎么实现了。</p><p>为了后面遍历操作数组，我需要开一个结构体，然后这个结构体需要有一个string来判断是圆形渲染还是矩形。同时要有它们对应的数值（如圆心）。当然还有有符号char，存储满足条件后的渲染结果</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">struct</span> <span class="title class_">Operation</span> &#123;</span><br><span class="line">    string type;</span><br><span class="line">    <span class="type">long</span> <span class="type">long</span> x, y, r; </span><br><span class="line">    <span class="type">long</span> <span class="type">long</span> x1, y1, x2, y2; </span><br><span class="line">    <span class="type">char</span> col;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></div></figure><p>然后就是没技术含量的存数组输入环节</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (op == <span class="string">&quot;Circle&quot;</span>) &#123;</span><br><span class="line">            Operation oper;</span><br><span class="line">            oper.type = <span class="string">&quot;Circle&quot;</span>;</span><br><span class="line">            ss &gt;&gt; oper.x &gt;&gt; oper.y &gt;&gt; oper.r &gt;&gt; oper.col;</span><br><span class="line">            operations.<span class="built_in">push_back</span>(oper);</span><br><span class="line">        &#125;</span><br></pre></td></tr></table></div></figure><p>大概这样，矩形同理。重点是当op&#x3D;&#x3D;render需要输出时</p><p>为了遍历每个点，我们需要两个for循环，每个点初始为’.’</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> (<span class="type">long</span> <span class="type">long</span> v = y2; v &gt;= y1; v--) &#123;</span><br><span class="line">               <span class="keyword">for</span> (<span class="type">long</span> <span class="type">long</span> u = x1; u &lt;= x2; u++) &#123;</span><br><span class="line">                   <span class="type">char</span> pixel = <span class="string">&#x27;.&#x27;</span>;</span><br><span class="line">                   <span class="comment">//pass</span></span><br><span class="line">                   cout&lt;&lt;pixel;</span><br><span class="line">           &#125;</span><br><span class="line">    cout &lt;&lt;endl;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>循环里面就是这个题目的思维核心，覆盖于是倒着遍历。</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> (<span class="type">int</span> i = operations.<span class="built_in">size</span>() - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--) &#123;</span><br><span class="line">                        Operation&amp; oper = operations[i]; </span><br><span class="line">                        <span class="keyword">if</span> (oper.type == <span class="string">&quot;Circle&quot;</span>) &#123;</span><br><span class="line">                            <span class="type">long</span> <span class="type">long</span> dx = u - oper.x;</span><br><span class="line">                            <span class="type">long</span> <span class="type">long</span> dy = v - oper.y;</span><br><span class="line">                           </span><br><span class="line">                            <span class="keyword">if</span> (dx * dx + dy * dy &lt;= oper.r * oper.r) &#123;</span><br><span class="line">                                pixel = oper.col;</span><br><span class="line">                                <span class="keyword">break</span>;</span><br><span class="line">                            &#125;</span><br><span class="line">                        &#125;</span><br><span class="line">                        <span class="keyword">else</span> <span class="keyword">if</span> (oper.type == <span class="string">&quot;Rectangle&quot;</span>) &#123;</span><br><span class="line">                            <span class="keyword">if</span> (u &gt;= oper.x1 &amp;&amp; u &lt;= oper.x2 &amp;&amp; v &gt;= oper.y1 &amp;&amp; v &lt;= oper.y2) &#123;</span><br><span class="line">                                pixel = oper.col;</span><br><span class="line">                                <span class="keyword">break</span>;</span><br><span class="line">                            &#125;</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br></pre></td></tr></table></div></figure><p>附上AC代码下班，注意要开longlong，否则wa 8</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">Operation</span> &#123;</span><br><span class="line">    string type;</span><br><span class="line">    <span class="type">long</span> <span class="type">long</span> x, y, r; </span><br><span class="line">    <span class="type">long</span> <span class="type">long</span> x1, y1, x2, y2; </span><br><span class="line">    <span class="type">char</span> col;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">solve</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="type">int</span> n;</span><br><span class="line">    cin &gt;&gt; n;</span><br><span class="line">    cin.<span class="built_in">ignore</span>(); </span><br><span class="line">    </span><br><span class="line">    vector&lt;Operation&gt; operations;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">        string line;</span><br><span class="line">        <span class="built_in">getline</span>(cin, line);</span><br><span class="line">        <span class="function">stringstream <span class="title">ss</span><span class="params">(line)</span></span>;</span><br><span class="line">        string op;</span><br><span class="line">        ss &gt;&gt; op;</span><br><span class="line">        </span><br><span class="line">        <span class="keyword">if</span> (op == <span class="string">&quot;Circle&quot;</span>) &#123;</span><br><span class="line">            Operation oper;</span><br><span class="line">            oper.type = <span class="string">&quot;Circle&quot;</span>;</span><br><span class="line">            ss &gt;&gt; oper.x &gt;&gt; oper.y &gt;&gt; oper.r &gt;&gt; oper.col;</span><br><span class="line">            operations.<span class="built_in">push_back</span>(oper);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span> <span class="keyword">if</span> (op == <span class="string">&quot;Rectangle&quot;</span>) &#123;</span><br><span class="line">            Operation oper;</span><br><span class="line">            oper.type = <span class="string">&quot;Rectangle&quot;</span>;</span><br><span class="line">            ss &gt;&gt; oper.x1 &gt;&gt; oper.y1 &gt;&gt; oper.x2 &gt;&gt; oper.y2 &gt;&gt; oper.col;</span><br><span class="line">            operations.<span class="built_in">push_back</span>(oper);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span> <span class="keyword">if</span> (op == <span class="string">&quot;Render&quot;</span>) &#123;</span><br><span class="line">            <span class="type">long</span> <span class="type">long</span> x1, y1, x2, y2;</span><br><span class="line">            ss &gt;&gt; x1 &gt;&gt; y1 &gt;&gt; x2 &gt;&gt; y2;</span><br><span class="line">            </span><br><span class="line">            <span class="keyword">for</span> (<span class="type">long</span> <span class="type">long</span> v = y2; v &gt;= y1; v--) &#123;</span><br><span class="line">                <span class="keyword">for</span> (<span class="type">long</span> <span class="type">long</span> u = x1; u &lt;= x2; u++) &#123;</span><br><span class="line">                    <span class="type">char</span> pixel = <span class="string">&#x27;.&#x27;</span>;</span><br><span class="line">               </span><br><span class="line">                    <span class="keyword">for</span> (<span class="type">int</span> i = operations.<span class="built_in">size</span>() - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--) &#123;</span><br><span class="line">                        <span class="keyword">auto</span>&amp; oper = operations[i];</span><br><span class="line">                        <span class="keyword">if</span> (oper.type == <span class="string">&quot;Circle&quot;</span>) &#123;</span><br><span class="line">                            <span class="type">long</span> <span class="type">long</span> dx = u - oper.x;</span><br><span class="line">                            <span class="type">long</span> <span class="type">long</span> dy = v - oper.y;</span><br><span class="line">                           </span><br><span class="line">                            <span class="keyword">if</span> (dx * dx + dy * dy &lt;= oper.r * oper.r) &#123;</span><br><span class="line">                                pixel = oper.col;</span><br><span class="line">                                <span class="keyword">break</span>;</span><br><span class="line">                            &#125;</span><br><span class="line">                        &#125;</span><br><span class="line">                        <span class="keyword">else</span> <span class="keyword">if</span> (oper.type == <span class="string">&quot;Rectangle&quot;</span>) &#123;</span><br><span class="line">                            <span class="keyword">if</span> (u &gt;= oper.x1 &amp;&amp; u &lt;= oper.x2 &amp;&amp; v &gt;= oper.y1 &amp;&amp; v &lt;= oper.y2) &#123;</span><br><span class="line">                                pixel = oper.col;</span><br><span class="line">                                <span class="keyword">break</span>;</span><br><span class="line">                            &#125;</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                    cout &lt;&lt; pixel;</span><br><span class="line">                &#125;</span><br><span class="line">                cout &lt;&lt; endl;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    ios::<span class="built_in">sync_with_stdio</span>(<span class="number">0</span>), cin.<span class="built_in">tie</span>(<span class="number">0</span>), cout.<span class="built_in">tie</span>(<span class="number">0</span>);</span><br><span class="line">    <span class="built_in">solve</span>();</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>]]></content>
      
      
      <categories>
          
          <category> 算法 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 算法 </tag>
            
            <tag> acm </tag>
            
            <tag> 模拟 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>链表</title>
      <link href="/2025/11/10/%E9%93%BE%E8%A1%A8/"/>
      <url>/2025/11/10/%E9%93%BE%E8%A1%A8/</url>
      
        <content type="html"><![CDATA[<p>本文将兼述<strong>数据结构</strong>这门课中链表的侧重点以及<strong>算法实战</strong>中链表的侧重点。</p>        <h1 id="什么是链表？"   >          <a href="#什么是链表？" class="heading-link"><i class="fas fa-link"></i></a><a href="#什么是链表？" class="headerlink" title="什么是链表？"></a>什么是链表？</h1>      <p>链表是一种用于<strong>存储数据</strong>的数据结构，通过<strong>像链条一般的指针</strong>连接元素（得名原因）。它是<strong>线性表</strong>的链式存储映像，称为<strong>线性表的链式存储结构</strong></p><p>它的显著优势是<strong>删除和插入数据</strong>十分方便（数组要O(n)，链表只需O(1)），但<strong>寻找和读取数据表现欠佳</strong>（数组只需O(1)，链表需要O(n)）。</p>        <h1 id="链表的组成分类"   >          <a href="#链表的组成分类" class="heading-link"><i class="fas fa-link"></i></a><a href="#链表的组成分类" class="headerlink" title="链表的组成分类"></a>链表的组成分类</h1>      <p>链表由一系列节点（node）组成，每个节点（同结点）有两个部分：</p><ul><li><strong>数据域</strong>：存储实际数据，(如int value）</li><li><strong>指针域</strong>： 存储下一个节点的地址（如 node *next）</li></ul><p>链表分为，单链表，双链表，循环链表。</p>        <h2 id="单链表"   >          <a href="#单链表" class="heading-link"><i class="fas fa-link"></i></a><a href="#单链表" class="headerlink" title="单链表"></a>单链表</h2>      <p>结点只有一个指针域，称为单链表或者线性链表。<strong>由表头唯一确定，所以可以用头指针的名字来命名</strong>。若头指针是L,则链表命名为L</p><p><img src="/../images/image-20251110112047267.png" alt="image-20251110112047267"></p><p>附上c++代码便于理解，但是后面会用到比较常见的typedef写法，所以这里的代码只是辅助理解，简洁为主。</p><p>注意：后文列举代码默认已定义Node结构体</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">struct</span> <span class="title class_">Node</span> &#123;</span><br><span class="line">  <span class="type">int</span> value;</span><br><span class="line">  Node *next;</span><br><span class="line">&#125;;<span class="comment">//比较好理解的写法，但是typedef更常用</span></span><br><span class="line"></span><br></pre></td></tr></table></div></figure>        <h2 id="双链表"   >          <a href="#双链表" class="heading-link"><i class="fas fa-link"></i></a><a href="#双链表" class="headerlink" title="双链表"></a>双链表</h2>      <p>有两个指针域(有左右之分)的链表，称为双链表</p><p><img src="/../images/image-20251110112101610.png" alt="image-20251110112101610"></p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">struct</span> <span class="title class_">Node</span> &#123;</span><br><span class="line">  <span class="type">int</span> value;</span><br><span class="line">  Node *left;</span><br><span class="line">  Node *right;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></div></figure>        <h2 id="循环链表"   >          <a href="#循环链表" class="heading-link"><i class="fas fa-link"></i></a><a href="#循环链表" class="headerlink" title="循环链表"></a>循环链表</h2>      <p>首尾相接的链表是循环列表。（尾节点的 <code>next</code> 指向<strong>头节点</strong>）由于这个特性，在插入数据时需要判断链表是否为空，为空则自身循环，不空则正常插入数据。（从循环链表中的任何一个节点都可以找到其他任何节点，而单链表不行）</p><p><img src="/../images/image-20251110135816396.png" alt="image-20251110135816396"></p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">insertNode</span><span class="params">(<span class="type">int</span> i, Node *p)</span> </span>&#123;</span><br><span class="line">  Node *node = <span class="keyword">new</span> Node;<span class="comment">//创建新节点</span></span><br><span class="line">  node-&gt;value = i;<span class="comment">//设置节点值</span></span><br><span class="line">  node-&gt;next = <span class="literal">NULL</span>;<span class="comment">//初始化next指针</span></span><br><span class="line">  <span class="keyword">if</span> (p == <span class="literal">NULL</span>) &#123;<span class="comment">//链表为空</span></span><br><span class="line">    p = node;<span class="comment">//p指向新节点</span></span><br><span class="line">    node-&gt;next = node;<span class="comment">//自己指向自己</span></span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    node-&gt;next = p-&gt;next;<span class="comment">//新节点指向p的后继</span></span><br><span class="line">    p-&gt;next = node;<span class="comment">//p指向新节点</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="链表常见运算符和关键字"   >          <a href="#链表常见运算符和关键字" class="heading-link"><i class="fas fa-link"></i></a><a href="#链表常见运算符和关键字" class="headerlink" title="链表常见运算符和关键字"></a>链表常见运算符和关键字</h2>      <p>初见代码你也许疑惑，new是什么？</p><p><strong>它是c++中的关键字，用于动态分配内存。</strong></p><p>例如</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> *p=<span class="keyword">new</span> <span class="type">int</span> <span class="comment">//分配一个int 大小的内存</span></span><br><span class="line"><span class="type">int</span> *p=<span class="keyword">new</span> <span class="built_in">int</span> (<span class="number">100</span>)<span class="comment">//初始值为100</span></span><br></pre></td></tr></table></div></figure><p><code>-&gt;</code>则是c&#x2F;c++中的箭头运算符，等价于，先解引用指针，然后访问成员。</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">Node* node=<span class="keyword">new</span> Node;</span><br><span class="line">    node-&gt;value=<span class="number">5</span>;<span class="comment">//设置节点的value为5，等价于（*node）.value=5</span></span><br><span class="line">    node-&gt;next=<span class="literal">NULL</span>;<span class="comment">//设置Next指针为NULL，等价于 (*node).next=NULL</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="链表的一些概念"   >          <a href="#链表的一些概念" class="heading-link"><i class="fas fa-link"></i></a><a href="#链表的一些概念" class="headerlink" title="链表的一些概念"></a>链表的一些概念</h2>      <p>我们还提到了头结点的概念，其实与之对应的还有尾结点，头指针，首元结点。</p><ul><li><strong>头指针</strong>：指向链表中第一个元素的指针</li><li><strong>首元结点</strong>：链表中存储第一个数据元素a1的结点</li><li><strong>头结点</strong>：是在链表的首元结点之前附设的一个结点，**数据域内可以为空，**只存放表长和空表标志等信息。<strong>但此结点不能计入链表长度值</strong></li></ul><p><strong>按有无头结点划分</strong></p><p><img src="/../images/image-20251110142744415.png" alt="image-20251110142744415"></p><p>有头结点时，当当头结点的指针域为空时表示空表。</p>        <h3 id="为什么要设置头结点？"   >          <a href="#为什么要设置头结点？" class="heading-link"><i class="fas fa-link"></i></a><a href="#为什么要设置头结点？" class="headerlink" title="为什么要设置头结点？"></a>为什么要设置头结点？</h3>      <ul><li><p><strong>便于首元结点的处理。</strong></p><p>**首元结点的地址保存在头结点的指针域中，**所以在链表的第一个位置上的操作和其他位置一致，无需进行特殊处理。</p></li><li><p>便于空表和非空表的统一</p><p>无论链表是否为空，<strong>头指针都是指向头结点的非空指针</strong>。</p></li></ul>        <h3 id="链表的特点"   >          <a href="#链表的特点" class="heading-link"><i class="fas fa-link"></i></a><a href="#链表的特点" class="headerlink" title="链表的特点"></a>链表的特点</h3>      <ul><li><p>结点在<strong>存储器中的位置是任意</strong>的，逻辑相邻的数据元素在物理上不一定相邻</p></li><li><p>访问时<strong>只能通过头指针进入链表</strong>，所以寻找第一个结点和最后一个结点的所需时间不等。</p></li></ul><p><strong>这种存取元素的方法称为<u>顺序存取法</u></strong></p>        <h1 id="单向链表的操作"   >          <a href="#单向链表的操作" class="heading-link"><i class="fas fa-link"></i></a><a href="#单向链表的操作" class="headerlink" title="单向链表的操作"></a>单向链表的操作</h1>      <ol><li>初始化 2.  取值 3.  查找 4.  插入 5.  删除</li></ol>        <h2 id="链表运算时间"   >          <a href="#链表运算时间" class="heading-link"><i class="fas fa-link"></i></a><a href="#链表运算时间" class="headerlink" title="链表运算时间"></a>链表运算时间</h2>      <p>查找：因线性链表只能顺序存取，所有查找时要从头指针找起，O(n)</p><p>插入删除：不需要移动元素，只需要修改指针，只需O(1).  <strong>但是，如果要在单链表中进行前插或删除操作，由于要从头查找前驱结点，所耗时间复杂度为</strong> <strong>O(n)</strong> 。</p>        <h2 id="初始化"   >          <a href="#初始化" class="heading-link"><i class="fas fa-link"></i></a><a href="#初始化" class="headerlink" title="初始化"></a>初始化</h2>      <p>注意，后文列举代码默认有此环境</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">ifndef</span> DULINKEDLIST_H</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> DULINKEDLIST_H</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 状态码定义</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> TRUE 1</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> FALSE 0</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> OK 1</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ERROR 0</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> INFEASIBLE -1</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> OVERFLOW -2</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 状态类型定义</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="type">int</span> Status;</span><br><span class="line"><span class="keyword">typedef</span> <span class="type">int</span> ElemType; <span class="comment">// 可根据需要修改元素类型</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">struct</span> <span class="title class_">LNode</span>&#123;</span><br><span class="line">    <span class="type">int</span> data;</span><br><span class="line">    <span class="keyword">struct</span> <span class="title class_">LNode</span> *next;</span><br><span class="line">&#125;LNode,*LinkList<span class="comment">//*LinkList为Lnode类型的指针</span></span><br><span class="line">    <span class="comment">//指针变量p表示结点地址</span></span><br><span class="line">    <span class="comment">//结点变量*p表示一个结点</span></span><br><span class="line">    <span class="comment">//注意：struct LNode结构体类型有了一个别名 LNode。</span></span><br><span class="line">    <span class="comment">//struct LNode *指针类型有了一个别名 LinkList。</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">//初始化构造一个空表</span></span><br><span class="line">    <span class="comment">//生成新结点作头结点，用头指针L指向头结点，头结点的指针域置空</span></span><br><span class="line">    <span class="function">Status <span class="title">InitList_L</span><span class="params">(LinkList &amp;L)</span></span>&#123;</span><br><span class="line">    L=<span class="keyword">new</span> LNode;</span><br><span class="line">    L-&gt;next=<span class="literal">NULL</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="取值"   >          <a href="#取值" class="heading-link"><i class="fas fa-link"></i></a><a href="#取值" class="headerlink" title="取值"></a>取值</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//获取链表中第i个元素的值</span></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">GetElem</span><span class="params">(LinkList L,<span class="type">int</span> i,ElemType &amp;e)</span></span>&#123;</span><br><span class="line">    LNode *p=L-&gt;next; <span class="comment">//p指向第一个结点（跳过头结点） 等价于LinkList p=L-&gt;next</span></span><br><span class="line">    <span class="type">int</span> j=<span class="number">1</span>;<span class="comment">//计数器</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">//遍历链表直到第i个节点或链表结束，p不为NULL时继续循环</span></span><br><span class="line">    <span class="keyword">while</span>(p &amp;&amp; j&lt;i)&#123;</span><br><span class="line">        p=p-&gt;next;</span><br><span class="line">        j++;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">if</span>(!p || j&gt;i)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125; </span><br><span class="line">    </span><br><span class="line">    e=p-&gt;data;<span class="comment">//通过指针参数返回元素值</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">使用示例</span><br><span class="line">LinkList list;<span class="comment">//初始化的链表</span></span><br><span class="line"><span class="type">int</span> value;</span><br><span class="line"><span class="keyword">if</span>(<span class="built_in">GetElem</span>(list,<span class="number">3</span>,&amp;value)==<span class="number">1</span>)&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;第三个元素是：%d\n&quot;</span>,value);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span>&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;第三个元素不存在\n&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="销毁"   >          <a href="#销毁" class="heading-link"><i class="fas fa-link"></i></a><a href="#销毁" class="headerlink" title="销毁"></a>销毁</h2>      <figure class="highlight c++"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">Status <span class="title">Destroy</span><span class="params">(LinkList &amp;L)</span></span>&#123;</span><br><span class="line">    LinkList p;<span class="comment">//用于临时保存要删除的节点</span></span><br><span class="line">    <span class="keyword">while</span>(L)&#123;<span class="comment">//当链表还有节点时继续循环</span></span><br><span class="line">        p=L;<span class="comment">//P指向当前要删除的节点</span></span><br><span class="line">        L=L-&gt;next;<span class="comment">//L移向下一个节点</span></span><br><span class="line">        <span class="keyword">delete</span> p;<span class="comment">//删除p指向的节点</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> OK;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="清空"   >          <a href="#清空" class="heading-link"><i class="fas fa-link"></i></a><a href="#清空" class="headerlink" title="清空"></a>清空</h2>      <figure class="highlight c++"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">Status <span class="title">Clear</span><span class="params">(LinkList &amp;L)</span></span>&#123;</span><br><span class="line">    LinkList p,q;</span><br><span class="line">    p=L-&gt;next;<span class="comment">//p指向第一个节点</span></span><br><span class="line">    <span class="keyword">while</span>(p)&#123;<span class="comment">//没到末尾</span></span><br><span class="line">        q=p-&gt;next;<span class="comment">//先保存下一个节点的地址，防止删除后丢失链表</span></span><br><span class="line">        <span class="keyword">delete</span> p;</span><br><span class="line">        p=q;</span><br><span class="line">    &#125;</span><br><span class="line">    L-&gt;next=<span class="literal">NULL</span>;<span class="comment">//头结点指针域为空</span></span><br><span class="line">    <span class="keyword">return</span> OK;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="查找"   >          <a href="#查找" class="heading-link"><i class="fas fa-link"></i></a><a href="#查找" class="headerlink" title="查找"></a>查找</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//在链表中查询值为e的节点</span></span><br><span class="line"><span class="function">LNode *<span class="title">LocateElem</span><span class="params">(LinkList L,Elemtype e)</span></span>&#123;</span><br><span class="line">    LNode *p = L-&gt;next;<span class="comment">//从第一个节点开始</span></span><br><span class="line">    <span class="keyword">while</span>(p &amp;&amp; p-&gt;data!=e)&#123;</span><br><span class="line">        p=p-&gt;Next;</span><br><span class="line">        j++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(p) <span class="keyword">return</span> j;</span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="求表长"   >          <a href="#求表长" class="heading-link"><i class="fas fa-link"></i></a><a href="#求表长" class="headerlink" title="求表长"></a>求表长</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">ListLength_L</span><span class="params">(LinkList L)</span></span>&#123;</span><br><span class="line">    LinkList p;</span><br><span class="line">    p=L-&gt;next;<span class="comment">//p指向第一个结点</span></span><br><span class="line">    i=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span>(p)&#123;</span><br><span class="line">        i++;</span><br><span class="line">        p=p-&gt;next;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> i;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="判断是否为空"   >          <a href="#判断是否为空" class="heading-link"><i class="fas fa-link"></i></a><a href="#判断是否为空" class="headerlink" title="判断是否为空"></a>判断是否为空</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">ListEmpty</span><span class="params">(LinkList L)</span></span>&#123;</span><br><span class="line">    <span class="comment">//若L为空表，则返回1，否则返回0</span></span><br><span class="line">    <span class="keyword">if</span>(L-&gt;next)&#123;<span class="comment">//非空</span></span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="前插法建单链表"   >          <a href="#前插法建单链表" class="heading-link"><i class="fas fa-link"></i></a><a href="#前插法建单链表" class="headerlink" title="前插法建单链表"></a>前插法建单链表</h2>      <p> 从一个空表开始重复读入数据</p><ul><li>生成新结点</li><li>将读入数据放到新节点</li><li>将该新节点插入到链表</li></ul><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">CreateList_F</span><span class="params">(LinkList &amp;L,<span class="type">int</span> n)</span></span>&#123;</span><br><span class="line">    L=<span class="keyword">new</span> LNode;</span><br><span class="line">    L-&gt;next=<span class="literal">NULL</span>;<span class="comment">//先建立一个带头结点的空链表</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=n;i&gt;<span class="number">0</span>;i--)&#123;</span><br><span class="line">        p=<span class="keyword">new</span> LNode;<span class="comment">//生成新节点</span></span><br><span class="line">        cin &gt;&gt;p-&gt;data;<span class="comment">//输入元素值</span></span><br><span class="line">        p-&gt;next=L-&gt;next;</span><br><span class="line">        L-&gt;next=p;<span class="comment">//插入到表头</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p><img src="/../images/image-20251111083610212.png" alt="image-20251111083610212"></p>        <h2 id="尾插法建单链表"   >          <a href="#尾插法建单链表" class="heading-link"><i class="fas fa-link"></i></a><a href="#尾插法建单链表" class="headerlink" title="尾插法建单链表"></a>尾插法建单链表</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">CreateList_L</span><span class="params">(LinkList &amp;L,<span class="type">int</span> n)</span></span>&#123;</span><br><span class="line">    L=<span class="keyword">new</span> LNode;</span><br><span class="line">    L-&gt;next=<span class="literal">NULL</span>;</span><br><span class="line">    r=L;<span class="comment">//尾指针r指向头结点</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">0</span>;i&lt;n;i++)&#123;</span><br><span class="line">        p=<span class="keyword">new</span> LNode;</span><br><span class="line">        cin &gt;&gt;p-&gt;data;</span><br><span class="line">        p-&gt;next=<span class="literal">NULL</span>;<span class="comment">//将新创建节点p的指针域设置为NULL，表示它是链表的最后一个节点。</span></span><br><span class="line">        r-&gt;next=p;<span class="comment">//将新节点链接到链表尾部</span></span><br><span class="line">        r=p;<span class="comment">//r指向新的尾结点</span></span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="插入（指定位置插入新节点）"   >          <a href="#插入（指定位置插入新节点）" class="heading-link"><i class="fas fa-link"></i></a><a href="#插入（指定位置插入新节点）" class="headerlink" title="插入（指定位置插入新节点）"></a>插入（指定位置插入新节点）</h2>      <p>算法步骤</p><p>找到插入位置的前驱节点，生成一个新结点，新结点的数据域置为x，新结点* s的指针域指向结点ai，结点*p的指针域指向新节点 *s</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//在第i个位置插入新元素e，所有要在i-1个节点后面插入</span></span><br><span class="line"><span class="function">Status <span class="title">ListInsert</span><span class="params">(LinkList &amp;L,<span class="type">int</span> i,ElemType e)</span></span>&#123;</span><br><span class="line">    LNode *p=L; <span class="comment">//p指向头结点</span></span><br><span class="line">    <span class="type">int</span> j=<span class="number">0</span>;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//寻找第i-1个节点p</span></span><br><span class="line">    <span class="keyword">while</span>(p &amp;&amp; j&lt;i<span class="number">-1</span>)&#123;</span><br><span class="line">        p=p-&gt;next;</span><br><span class="line">        j++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//i小于0或大于表长加一</span></span><br><span class="line">    <span class="keyword">if</span>(!p || j&gt;i<span class="number">-1</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> ERROR;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//创建新节点</span></span><br><span class="line">    s=<span class="keyword">new</span> LNode;</span><br><span class="line">    s-&gt;data=e;</span><br><span class="line">    <span class="comment">//插入操作,在第i-1个节点也就是p节点后插入新节点</span></span><br><span class="line">    <span class="comment">//先让新节点指向p原来的下一个节点</span></span><br><span class="line">    s-&gt;next=p-&gt;next;<span class="comment">//如果s=p-&gt;next，指针s会直接指向p-&gt;next指向的节点，新节点会丢失</span></span><br><span class="line">    p-&gt;next =s;<span class="comment">//在让p指向新节点</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> OK;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="删除-q"   >          <a href="#删除-q" class="heading-link"><i class="fas fa-link"></i></a><a href="#删除-q" class="headerlink" title="删除(q)"></a>删除(q)</h2>      <p>找到ai-1存储位置p</p><p>临时保存结点ai的地址在q中，以备释放</p><p>令p-&gt;next指向ai的后继节点</p><p>将ai的值保存在e中</p><p>释放ai空间</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//删除第i个节点，通过e返回其值</span></span><br><span class="line"><span class="function">Status <span class="title">ListDelete</span><span class="params">(LinkList L,<span class="type">int</span> i,<span class="type">int</span> &amp;e)</span></span>&#123;</span><br><span class="line">    LNode *p=L;</span><br><span class="line">    <span class="type">int</span> j=<span class="number">0</span>;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//寻找第i-1个节点,p的下一个节点存在时继续循环</span></span><br><span class="line">    <span class="keyword">while</span>(p-&gt;next &amp;&amp; j&lt;i<span class="number">-1</span>)&#123;</span><br><span class="line">        p=p-&gt;next;</span><br><span class="line">        j++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//删除位置不合理</span></span><br><span class="line">    <span class="keyword">if</span>(!(p-&gt;next) || j&gt;i<span class="number">-1</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    LNode *q=p-&gt;next;<span class="comment">//q指向要删除的节点</span></span><br><span class="line">    e=q-&gt;data;<span class="comment">//保存被删除节点的值</span></span><br><span class="line">    p-&gt;next=q-&gt;next;<span class="comment">//绕过要删除的节点</span></span><br><span class="line">    <span class="keyword">delete</span> q;<span class="comment">//释放内存</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    </span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><blockquote><p>[!NOTE]</p><p>关于p-&gt;next &#x3D; q-&gt;next的绕过原理</p><p>假设一个链表 头节点-&gt; A-&gt;B-&gt;C-&gt;NULL</p><p>p指向节点A,则p-&gt;next指向节点B，即q。</p><p>q-&gt;next指向c。</p><p>p-&gt;next&#x3D;q-&gt;next就是直接让A指向C</p></blockquote>        <h1 id="单向循环链表的操作及约瑟夫环"   >          <a href="#单向循环链表的操作及约瑟夫环" class="heading-link"><i class="fas fa-link"></i></a><a href="#单向循环链表的操作及约瑟夫环" class="headerlink" title="单向循环链表的操作及约瑟夫环"></a>单向循环链表的操作及约瑟夫环</h1>              <h2 id="初始化-1"   >          <a href="#初始化-1" class="heading-link"><i class="fas fa-link"></i></a><a href="#初始化-1" class="headerlink" title="初始化"></a>初始化</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 通常在头文件中这样定义</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> OK 1</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ERROR 0</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> OVERFLOW -1</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="type">int</span> Status;  <span class="comment">// 将Status定义为int类型</span></span><br><span class="line"><span class="function">Status <span class="title">InitList_CL</span><span class="params">(LinkList &amp;L)</span></span>&#123;</span><br><span class="line">    L=<span class="keyword">new</span> LNode;<span class="comment">//生成头结点</span></span><br><span class="line">    <span class="keyword">if</span>(!L) <span class="built_in">exit</span>(OVERLOW);<span class="comment">//内存分配失败</span></span><br><span class="line">    L-&gt;next=L;<span class="comment">//头结点的next指向自己，形成空环</span></span><br><span class="line">    <span class="keyword">return</span> OK;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="判断是否为空-1"   >          <a href="#判断是否为空-1" class="heading-link"><i class="fas fa-link"></i></a><a href="#判断是否为空-1" class="headerlink" title="判断是否为空"></a>判断是否为空</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">ListEmpty_CL</span><span class="params">(LinkList L)</span></span>&#123;</span><br><span class="line">    <span class="comment">//判断头结点的next是否指向自己</span></span><br><span class="line">    <span class="keyword">return</span> (L-&gt;next==L);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="结点p之前插入新结点s"   >          <a href="#结点p之前插入新结点s" class="heading-link"><i class="fas fa-link"></i></a><a href="#结点p之前插入新结点s" class="headerlink" title="结点p之前插入新结点s"></a>结点p之前插入新结点s</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">Status <span class="title">ListInsert_CL</span><span class="params">(LinkList &amp;L,LNode *p,EleType e)</span></span>&#123;</span><br><span class="line">    LNode *s=<span class="keyword">new</span> LNode;</span><br><span class="line">    <span class="keyword">if</span>(!s)<span class="keyword">return</span> ERROR;</span><br><span class="line">    s-&gt;data=e;</span><br><span class="line">    </span><br><span class="line">    s-&gt;next=p-&gt;next;<span class="comment">//新结点s指向p的后继</span></span><br><span class="line">    p-&gt;next=s;<span class="comment">//结点p指向新结点s</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">//如果p是尾结点，那么s就成为新的尾结点，其next头指向头结点L</span></span><br><span class="line">    <span class="keyword">return</span> OK;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="删除点p的后继节点"   >          <a href="#删除点p的后继节点" class="heading-link"><i class="fas fa-link"></i></a><a href="#删除点p的后继节点" class="headerlink" title="删除点p的后继节点"></a>删除点p的后继节点</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">Status <span class="title">ListDelete_CL</span><span class="params">(LinkList &amp;L,LNode *p,EleType &amp;e)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(p-&gt;next==L)<span class="keyword">return</span> ERRER;</span><br><span class="line">    <span class="comment">//p是尾结点，无后续可删</span></span><br><span class="line">    </span><br><span class="line">    LNode *q=p-&gt;next;<span class="comment">//q指向要删除的结点</span></span><br><span class="line">    e=q-&gt;data;<span class="comment">//保存被删除的结点位置</span></span><br><span class="line">    p-&gt;next=q-&gt;next;<span class="comment">//绕过要删除的结点</span></span><br><span class="line">    <span class="keyword">delete</span> q;<span class="comment">//释放内存</span></span><br><span class="line">    <span class="keyword">return</span> OK;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="合并链表"   >          <a href="#合并链表" class="heading-link"><i class="fas fa-link"></i></a><a href="#合并链表" class="headerlink" title="合并链表"></a>合并链表</h2>      <p><code>Ta</code>是链表a的尾指针，<code>Ta-&gt;next</code>指向链表a的头结点。</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">LinkList <span class="title">Connect</span><span class="params">(LinkList Ta,Linklist Tb)</span></span>&#123;</span><br><span class="line">    <span class="comment">//假设ta,tb都是非空单循环链表</span></span><br><span class="line">    p=Ta-&gt;next<span class="comment">//p存表头结点</span></span><br><span class="line">    Ta-&gt;next = Tb -&gt;next-&gt;next;<span class="comment">//tb表头连接Ta表尾</span></span><br><span class="line">    <span class="keyword">delete</span> Tb-&gt;next;<span class="comment">//释放tb表头结点,现在链表a的尾直接指向了链表b的首元结点，链表b原来的头结点（Tb-&gt;next）已经不再被需要。</span></span><br><span class="line">    Tb-&gt;next=p;<span class="comment">//修改指针</span></span><br><span class="line">    <span class="keyword">return</span> Tb;</span><br><span class="line">    <span class="comment">/*现在，整个链表的尾部是链表b原来的尾节点（即 Tb指向的节点）。</span></span><br><span class="line"><span class="comment">要让新链表成为循环链表，需要让尾节点的 next指针指向头结点。</span></span><br><span class="line"><span class="comment">p保存的正是链表a原来的头结点，现在它将成为合并后新链表的头结点。</span></span><br><span class="line"><span class="comment">这行代码让链表b的尾节点（Tb）的 next指针指向这个头结点，从而闭合整个链表，形成一个新的循环链表。</span></span><br><span class="line"><span class="comment">合并完成后，Tb指向的是新链表的尾节点。</span></span><br><span class="line"><span class="comment">函数返回 Tb，即返回新循环链表的尾指针。</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="约瑟夫环"   >          <a href="#约瑟夫环" class="heading-link"><i class="fas fa-link"></i></a><a href="#约瑟夫环" class="headerlink" title="约瑟夫环"></a>约瑟夫环</h2>      <p><img src="/../images/image-20251110212825259.png" alt="image-20251110212825259"></p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">Josephus</span><span class="params">(<span class="type">int</span> n, <span class="type">int</span> m)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 创建包含n个结点的循环链表</span></span><br><span class="line">    LinkList L, current, prev;</span><br><span class="line">    <span class="built_in">InitList_CL</span>(L);  <span class="comment">// 初始化循环链表</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 构建约瑟夫环</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        <span class="built_in">ListInsert_CL</span>(L, i, i);  <span class="comment">// 第i个人的编号为i</span></span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    current = L-&gt;next;  <span class="comment">// 从第一个人开始</span></span><br><span class="line">    prev = L;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">while</span>(n &gt; <span class="number">1</span>) &#123;</span><br><span class="line">        <span class="comment">// 数到第m个人</span></span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> count = <span class="number">1</span>; count &lt; m; count++) &#123;</span><br><span class="line">            prev = current;</span><br><span class="line">            current = current-&gt;next;</span><br><span class="line">            <span class="comment">// 如果遇到头结点，跳过</span></span><br><span class="line">            <span class="keyword">if</span>(current == L) &#123;</span><br><span class="line">                prev = current;</span><br><span class="line">                current = current-&gt;next;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 删除当前结点（淘汰这个人）</span></span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;出列的人是：%d\n&quot;</span>, current-&gt;data);</span><br><span class="line">        prev-&gt;next = current-&gt;next;</span><br><span class="line">        <span class="keyword">delete</span> current;</span><br><span class="line">        current = prev-&gt;next;</span><br><span class="line">        n--;</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 如果遇到头结点，跳过</span></span><br><span class="line">        <span class="keyword">if</span>(current == L) &#123;</span><br><span class="line">            current = current-&gt;next;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;最后剩下的人是：%d\n&quot;</span>, current-&gt;data);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="双向链表"   >          <a href="#双向链表" class="heading-link"><i class="fas fa-link"></i></a><a href="#双向链表" class="headerlink" title="双向链表"></a>双向链表</h1>              <h2 id="定义初始化"   >          <a href="#定义初始化" class="heading-link"><i class="fas fa-link"></i></a><a href="#定义初始化" class="headerlink" title="定义初始化"></a>定义初始化</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="keyword">struct</span> <span class="title class_">DuLNode</span>&#123;</span><br><span class="line">    EleType data;</span><br><span class="line">    <span class="keyword">struct</span> <span class="title class_">DuLNode</span> *prior;</span><br><span class="line">    <span class="keyword">struct</span> <span class="title class_">DuLNode</span> *next;</span><br><span class="line">&#125;DuLNode,*DuLLinkList</span><br><span class="line">    </span><br></pre></td></tr></table></div></figure>        <h2 id="插入"   >          <a href="#插入" class="heading-link"><i class="fas fa-link"></i></a><a href="#插入" class="headerlink" title="插入"></a>插入</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 函数功能：在带头结点的双向链表L中，第i个位置之前插入新元素e</span></span><br><span class="line"><span class="comment">// 参数说明：L-双向链表头指针（引用传递），i-插入位置，e-待插入元素</span></span><br><span class="line"><span class="comment">// 返回值：操作状态（OK-成功，ERROR-失败）</span></span><br><span class="line"><span class="function">Status <span class="title">ListInsert_DuL</span><span class="params">(DuLinkList &amp;L, <span class="type">int</span> i, ElemType e)</span> </span>&#123;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 步骤1：定位插入位置，获取第i个结点的指针p</span></span><br><span class="line">    <span class="comment">// 注意：这里是在第i个结点&quot;之前&quot;插入，所以p指向的是目标位置的后继结点</span></span><br><span class="line">    DuLNode *p;</span><br><span class="line">    <span class="keyword">if</span>(!(p = <span class="built_in">GetElemP_DuL</span>(L, i)))  <span class="comment">// 调用查找函数获取第i个结点的地址</span></span><br><span class="line">        <span class="keyword">return</span> ERROR;               <span class="comment">// 如果第i个结点不存在，返回错误</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 步骤2：创建新结点并赋值</span></span><br><span class="line">    DuLNode *s = <span class="keyword">new</span> DuLNode;  <span class="comment">// 动态分配新结点内存</span></span><br><span class="line">    s-&gt;data = e;               <span class="comment">// 将数据e存入新结点的数据域</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 步骤3：核心操作 - 四步指针修改，将新结点s插入到p结点之前</span></span><br><span class="line">    <span class="comment">// 这四步操作必须按顺序执行，确保链表不断链</span></span><br><span class="line">    </span><br><span class="line">    s-&gt;prior = p-&gt;prior;      <span class="comment">// 操作①：新结点s的前驱指向p原来的前驱结点</span></span><br><span class="line">    p-&gt;prior-&gt;next = s;       <span class="comment">// 操作②：p原前驱结点的后继指向新结点s</span></span><br><span class="line">    s-&gt;next = p;              <span class="comment">// 操作③：新结点s的后继指向p结点</span></span><br><span class="line">    p-&gt;prior = s;             <span class="comment">// 操作④：p结点的前驱指向新结点s</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> OK;  <span class="comment">// 插入成功，返回OK状态</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="删除"   >          <a href="#删除" class="heading-link"><i class="fas fa-link"></i></a><a href="#删除" class="headerlink" title="删除"></a>删除</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 函数功能：删除带头结点的双向链表L中第i个位置的元素，并通过e返回被删除的值</span></span><br><span class="line"><span class="comment">// 参数说明：L-双向链表头指针（引用传递），i-删除位置，e-用于返回被删除元素值的引用</span></span><br><span class="line"><span class="comment">// 返回值：操作状态（OK-成功，ERROR-失败）</span></span><br><span class="line"><span class="function">Status <span class="title">ListDelete_DuL</span><span class="params">(DuLinkList &amp;L, <span class="type">int</span> i, ElemType &amp;e)</span> </span>&#123;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 步骤1：定位要删除的结点，获取第i个结点的指针p</span></span><br><span class="line">    DuLNode *p;</span><br><span class="line">    <span class="keyword">if</span>(!(p = <span class="built_in">GetElemP_DuL</span>(L, i)))     <span class="comment">// 调用查找函数获取第i个结点的地址</span></span><br><span class="line">        <span class="keyword">return</span> ERROR;                 <span class="comment">// 如果第i个结点不存在，返回错误</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 步骤2：保存被删除结点的数据值</span></span><br><span class="line">    e = p-&gt;data;    <span class="comment">// 将待删除结点p的数据域值保存到参数e中，以便返回给调用者</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 步骤3：核心操作 - 两步指针修改，将结点p从链表中&quot;摘除&quot;</span></span><br><span class="line">    <span class="comment">// 关键思想：让p的前驱结点直接指向p的后继结点，绕过p本身</span></span><br><span class="line">    </span><br><span class="line">    p-&gt;prior-&gt;next = p-&gt;next;    <span class="comment">// 操作①：p前驱结点的后继指针指向p的后继结点</span></span><br><span class="line">    p-&gt;next-&gt;prior = p-&gt;prior;  <span class="comment">// 操作②：p后继结点的前驱指针指向p的前驱结点</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 步骤4：释放被删除结点的内存空间</span></span><br><span class="line">    <span class="keyword">delete</span> p;        <span class="comment">// 释放结点p占用的内存，防止内存泄漏</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> OK;       <span class="comment">// 删除成功，返回OK状态</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="有序链表合并"   >          <a href="#有序链表合并" class="heading-link"><i class="fas fa-link"></i></a><a href="#有序链表合并" class="headerlink" title="有序链表合并"></a>有序链表合并</h1>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 函数功能：将两个非递减有序的带头结点的单链表La和Lb合并为一个新的非递减有序链表Lc</span></span><br><span class="line"><span class="comment">// 核心思想：通过指针操作，重用La和Lb的现有节点，不分配新的节点内存</span></span><br><span class="line"><span class="comment">// 参数说明：La, Lb-待合并的有序链表；Lc-合并后的新链表（引用传递）</span></span><br><span class="line"><span class="comment">// 返回值：无（通过Lc参数返回结果）</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">MergeList_L</span><span class="params">(LinkList &amp;La, LinkList &amp;Lb, LinkList &amp;Lc)</span> </span>&#123;</span><br><span class="line">   <span class="comment">// 步骤1：初始化工作指针，跳过头结点，指向第一个数据节点</span></span><br><span class="line">   pa = La-&gt;next;  <span class="comment">// pa指向链表La的第一个数据节点（首元结点）</span></span><br><span class="line">   pb = Lb-&gt;next;  <span class="comment">// pb指向链表Lb的第一个数据节点</span></span><br><span class="line">   </span><br><span class="line">   <span class="comment">// 步骤2：设置合并后链表Lc的头结点，并初始化尾指针pc</span></span><br><span class="line">   pc = Lc = La;   <span class="comment">// 重用La的头结点作为Lc的头结点，pc作为Lc的当前尾指针</span></span><br><span class="line">   </span><br><span class="line">   <span class="comment">// 步骤3：核心循环 - 比较并合并两个链表的节点</span></span><br><span class="line">   <span class="comment">// 循环条件：两个链表都还有未处理的节点（pa和pb都不为NULL）</span></span><br><span class="line">   <span class="keyword">while</span>(pa &amp;&amp; pb) &#123;</span><br><span class="line">      <span class="comment">// 比较当前两个节点的大小，选择较小的节点链接到Lc</span></span><br><span class="line">      <span class="keyword">if</span>(pa-&gt;data &lt;= pb-&gt;data) &#123; </span><br><span class="line">         <span class="comment">// La的当前节点值较小或相等，将其链接到Lc末尾</span></span><br><span class="line">         pc-&gt;next = pa;  <span class="comment">// 将pa节点挂接到pc之后</span></span><br><span class="line">         pc = pa;        <span class="comment">// pc指针移动到新的尾节点pa</span></span><br><span class="line">         pa = pa-&gt;next;  <span class="comment">// pa指针后移，准备处理La的下一个节点</span></span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">else</span> &#123;</span><br><span class="line">         <span class="comment">// Lb的当前节点值较小，将其链接到Lc末尾</span></span><br><span class="line">         pc-&gt;next = pb;  <span class="comment">// 将pb节点挂接到pc之后</span></span><br><span class="line">         pc = pb;        <span class="comment">// pc指针移动到新的尾节点pb</span></span><br><span class="line">         pb = pb-&gt;next;  <span class="comment">// pb指针后移，准备处理Lb的下一个节点</span></span><br><span class="line">      &#125;</span><br><span class="line">   &#125; <span class="comment">// 结束循环时，pa和pb中至少有一个为NULL</span></span><br><span class="line">   </span><br><span class="line">   <span class="comment">// 步骤4：处理剩余节点 - 将未处理完的链表直接连接到Lc末尾</span></span><br><span class="line">   pc-&gt;next = pa ? pa : pb;  <span class="comment">// 如果pa不为空则连接La剩余部分，否则连接Lb剩余部分</span></span><br><span class="line">   </span><br><span class="line">   <span class="comment">// 步骤5：资源清理 - 释放Lb的头结点（数据节点已全部并入Lc）</span></span><br><span class="line">   <span class="keyword">delete</span> Lb;  <span class="comment">// Lb的头结点已不再需要，释放其内存空间</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>]]></content>
      
      
      <categories>
          
          <category> 算法 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 算法 </tag>
            
            <tag> acm </tag>
            
            <tag> 数据结构 </tag>
            
            <tag> 链表 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>图论-图的存储（1）</title>
      <link href="/2025/11/05/%E5%9B%BE%E8%AE%BA/"/>
      <url>/2025/11/05/%E5%9B%BE%E8%AE%BA/</url>
      
        <content type="html"><![CDATA[<p>本文基础：请确保你学过<span class="exturl"><a class="exturl__link"   href="https://oi-wiki.org/graph/concept/" >图论基本知识</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span>，vector的基本用法，结构体，以及一些dfs与链表知识</p>        <h1 id="图的存储"   >          <a href="#图的存储" class="heading-link"><i class="fas fa-link"></i></a><a href="#图的存储" class="headerlink" title="图的存储"></a>图的存储</h1>      <blockquote><p><strong>问题引入</strong>：</p><p>给定一个有向图，包含n个顶点和m条边，计算该图中连通分量的数量</p><p><strong>输入格式：</strong></p><p>第一行两个整数n,m</p><p>接下来m行，每行两个整数u,v.表示顶点u与顶点v之间有一条边</p><p><strong>输出格式:</strong></p><p>输出一个整数，表示联通分量的数量</p><p><strong>输入</strong></p><p>5 3<br>1 2<br>2 3<br>4 5</p><p><strong>输出</strong></p><p>2</p><p><strong>解释</strong></p><p>顶点1、2、3形成一个连通分量，顶点4、5形成另一个连通分量，因此共有2个连通分量。</p></blockquote>        <h2 id="初步阶段：直接存边"   >          <a href="#初步阶段：直接存边" class="heading-link"><i class="fas fa-link"></i></a><a href="#初步阶段：直接存边" class="headerlink" title="初步阶段：直接存边"></a>初步阶段：直接存边</h2>      <p>很明显，我们只需要联通分量的数量，那么什么是联通分量？</p><p><strong>如果从某个顶点进行遍历，能够到达的所有顶点必然属于同一个联通变量</strong></p><p>也就是说<strong>连通性&#x3D;可达性</strong></p><p>那我们就有了一个朴素的思想，<strong>dfs探索可达性</strong></p><p>准备阶段，我们用一个数组来记录每一条边，数组的每个元素包含起点终点。再用另一个数组标记顶点是否被访问。</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">struct</span> <span class="title class_">edge</span>&#123;</span><br><span class="line"><span class="type">int</span> u,v;<span class="comment">//边的起点和终点</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">vector&lt;edge&gt;e;<span class="comment">//存储所有边的数组</span></span><br><span class="line">vector&lt;<span class="type">bool</span>&gt;vis;<span class="comment">//标记顶点是否被访问过</span></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    cin &gt;&gt;n&gt;&gt;m;</span><br><span class="line">    vis.<span class="built_in">resize</span>(n<span class="number">+1</span>,<span class="number">0</span>);</span><br><span class="line">    e.<span class="built_in">resize</span>(m<span class="number">+1</span>);</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">1</span>;i&lt;=m;i++)&#123;</span><br><span class="line">        cin &gt;&gt;e[i].u&gt;&gt;e[i].v;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>那么dfs部分怎么写呢？我写dfs的目的是什么，<strong>是我能通过一个u节点到达哪个节点。</strong></p><p>那我遍历每一条边，找到所有以u为起点的边，再以访问到的边为起点继续递归访问，边访问边标记。如果访问到已经访问到的节点就直接返回。</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> u)</span> </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (vis[u]) <span class="keyword">return</span>;     <span class="comment">// 基线条件：如果已访问，直接返回</span></span><br><span class="line">  vis[u] = <span class="literal">true</span>;          <span class="comment">// 标记当前顶点为已访问</span></span><br><span class="line">  </span><br><span class="line">  <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= m; ++i) &#123;     <span class="comment">// 遍历所有边</span></span><br><span class="line">    <span class="keyword">if</span> (e[i].u == u) &#123;               <span class="comment">// 找到以u为起点的边</span></span><br><span class="line">      <span class="built_in">dfs</span>(e[i].v);                   <span class="comment">// 递归访问终点v</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>插一句题外话，可以遍历节点，那也可以遍历边来查找边。就像这样。(与本题无关)</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">bool</span> <span class="title">find_edge</span><span class="params">(<span class="type">int</span> u, <span class="type">int</span> v)</span> </span>&#123;</span><br><span class="line">  <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= m; ++i) &#123;    <span class="comment">// 遍历所有边</span></span><br><span class="line">    <span class="keyword">if</span> (e[i].u == u &amp;&amp; e[i].v == v) &#123;</span><br><span class="line">      <span class="keyword">return</span> <span class="literal">true</span>;  <span class="comment">// 找到从u到v的边</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> <span class="literal">false</span>;     <span class="comment">// 未找到</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>好的，那么附上完整代码</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;vector&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">Edge</span> &#123;</span><br><span class="line">  <span class="type">int</span> u, v;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> n, m;</span><br><span class="line">vector&lt;Edge&gt; e;</span><br><span class="line">vector&lt;<span class="type">bool</span>&gt; vis;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> u)</span> </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (vis[u]) <span class="keyword">return</span>;</span><br><span class="line">  vis[u] = <span class="literal">true</span>;</span><br><span class="line">  <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= m; ++i) &#123;</span><br><span class="line">    <span class="keyword">if</span> (e[i].u == u) &#123;</span><br><span class="line">      <span class="built_in">dfs</span>(e[i].v);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">  cin &gt;&gt; n &gt;&gt; m;</span><br><span class="line"></span><br><span class="line">  vis.<span class="built_in">resize</span>(n + <span class="number">1</span>, <span class="literal">false</span>);</span><br><span class="line">  e.<span class="built_in">resize</span>(m + <span class="number">1</span>);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= m; ++i) &#123;</span><br><span class="line">    cin &gt;&gt; e[i].u &gt;&gt; e[i].v;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="type">int</span> count = <span class="number">0</span>;  <span class="comment">// 连通分量计数器</span></span><br><span class="line">  </span><br><span class="line">  <span class="comment">// 遍历所有顶点</span></span><br><span class="line">  <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; ++i) &#123;</span><br><span class="line">    <span class="keyword">if</span> (!vis[i]) &#123;  <span class="comment">// 如果顶点未被访问过</span></span><br><span class="line">      count++;      <span class="comment">// 发现一个新的连通分量</span></span><br><span class="line">      <span class="built_in">dfs</span>(i);       <span class="comment">// 遍历整个连通分量</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  cout &lt;&lt; count &lt;&lt; endl;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>观察一下这个做法的时间复杂度：</p><p>查询是否存在某条边：𝑂(𝑚)<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="O(m)">。</p><p>遍历一个点的所有出边：𝑂(𝑚)<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="O(m)">。</p><p>遍历整张图：𝑂(𝑛𝑚)<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="O(nm)">。</p><p>空间复杂度：𝑂(𝑚)<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="O(m)">。</p><p>每一次都要遍历图，时间复杂度还是不小的。因此人们提出了另一种思想</p>        <h2 id="中级阶段：邻接矩阵"   >          <a href="#中级阶段：邻接矩阵" class="heading-link"><i class="fas fa-link"></i></a><a href="#中级阶段：邻接矩阵" class="headerlink" title="中级阶段：邻接矩阵"></a>中级阶段：邻接矩阵</h2>      <p>由于每条边都有两个节点，<strong>两个节点间只存在两个状态——有边和无边。</strong></p><p>我们自然的想到可以建一个二维数组，<strong>用对应位置的0&#x2F;1来表示有无边连接。</strong></p><p>假设关系：A认识B, A认识C, B认识D, C认识D</p><p>那么对应的邻接矩阵就是这样的</p><p><img src="/../images/image-20251105194021935.png" alt="image-20251105194021935"></p><p>所以它的精髓就是，<strong>用二维表格清晰表达顶点间关系，通过行列索引判断连通性。</strong></p><p>所以有了一个最显著的优点，o1判断是否存在边</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">bool</span> <span class="title">find_edge</span><span class="params">(<span class="type">int</span> u,<span class="type">int</span> v)</span></span>&#123;<span class="keyword">return</span> adj[u][v];&#125;</span><br></pre></td></tr></table></div></figure><p>我们仍然用vector来进行矩阵的定义和初始化</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">vector&lt;vector&lt;<span class="type">bool</span>&gt;&gt;adj;<span class="comment">//邻接矩阵</span></span><br><span class="line">adj.<span class="built_in">resize</span>(n<span class="number">+1</span>,<span class="built_in">vector</span>&lt;<span class="type">bool</span>&gt;(n<span class="number">+1</span>,<span class="literal">false</span>));<span class="comment">//创建n*n矩阵，初始没有边连接</span></span><br><span class="line"><span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">1</span>;i&lt;=m;i++)&#123;</span><br><span class="line">    <span class="type">int</span> u,v;</span><br><span class="line">    cin &gt;&gt;u&gt;&gt;v;</span><br><span class="line">    adj[u][v]==<span class="literal">true</span>;<span class="comment">//标记边存在</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></div></figure><p>有了邻接矩阵，我们的dfs也可以优化了。因为我们要找节点u能到达的，实际只需要横着找一遍</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> u)</span></span>&#123;</span><br><span class="line"><span class="keyword">if</span>(vis[u]) <span class="keyword">return</span>;</span><br><span class="line">vis[u]==<span class="literal">true</span>;</span><br><span class="line"><span class="keyword">for</span>(<span class="type">int</span> v=<span class="number">1</span>;v&lt;=n;v++)&#123;</span><br><span class="line">        <span class="keyword">if</span>(adj[u][v] &amp;&amp; !vis[v])&#123;</span><br><span class="line">            <span class="built_in">dfs</span>(v);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>附上完整代码~</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;vector&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> n, m;</span><br><span class="line">vector&lt;vector&lt;<span class="type">bool</span>&gt;&gt; adj;  <span class="comment">// 邻接矩阵</span></span><br><span class="line">vector&lt;<span class="type">bool</span>&gt; vis;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> u)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (vis[u]) <span class="keyword">return</span>;</span><br><span class="line">    vis[u] = <span class="literal">true</span>;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 有向图：只遍历从u出发的边（u→v方向）</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> v = <span class="number">1</span>; v &lt;= n; ++v) &#123;</span><br><span class="line">        <span class="keyword">if</span> (adj[u][v] &amp;&amp; !vis[v]) &#123;  <span class="comment">// 存在边 u→v 且v未访问</span></span><br><span class="line">            <span class="built_in">dfs</span>(v);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    cin &gt;&gt; n &gt;&gt; m;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 初始化邻接矩阵（n+1)×(n+1)，全部为false</span></span><br><span class="line">    adj.<span class="built_in">resize</span>(n + <span class="number">1</span>, <span class="built_in">vector</span>&lt;<span class="type">bool</span>&gt;(n + <span class="number">1</span>, <span class="literal">false</span>));</span><br><span class="line">    vis.<span class="built_in">resize</span>(n + <span class="number">1</span>, <span class="literal">false</span>);</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 输入有向边</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= m; ++i) &#123;</span><br><span class="line">        <span class="type">int</span> u, v;</span><br><span class="line">        cin &gt;&gt; u &gt;&gt; v;</span><br><span class="line">        adj[u][v] = <span class="literal">true</span>;  <span class="comment">// 只标记u→v方向</span></span><br><span class="line">        <span class="comment">// 注意：这里没有 adj[v][u] = true（有向图的关键区别！）</span></span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="type">int</span> count = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; ++i) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!vis[i]) &#123;</span><br><span class="line">            count++;</span><br><span class="line">            <span class="built_in">dfs</span>(i);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;有向图连通分量数量: &quot;</span> &lt;&lt; count &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>插一句题外话，其实有向图和无向图的差别只在于</p><p>无向图的边是双向的，要考虑两个方向</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 输入无向边时，同时标记两个方向</span></span><br><span class="line"><span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= m; ++i) &#123;</span><br><span class="line">    <span class="type">int</span> u, v;</span><br><span class="line">    cin &gt;&gt; u &gt;&gt; v;</span><br><span class="line">    adj[u][v] = <span class="literal">true</span>;  <span class="comment">// u→v</span></span><br><span class="line">    adj[v][u] = <span class="literal">true</span>;  <span class="comment">// v→u （关键！让矩阵对称）</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// DFS遍历保持不变（因为矩阵已经对称）</span></span><br><span class="line"><span class="keyword">for</span> (<span class="type">int</span> v = <span class="number">1</span>; v &lt;= n; ++v) &#123;</span><br><span class="line">    <span class="keyword">if</span> (adj[u][v]) &#123;  <span class="comment">// 现在只需要检查一个方向</span></span><br><span class="line">        <span class="built_in">dfs</span>(v);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>同样的附上时间复杂度</p><p>查询是否存在某条边：𝑂(1)<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="O(1)">。</p><p>遍历一个点的所有出边：𝑂(𝑛)<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="O(n)">。</p><p>遍历整张图：𝑂(𝑛2)<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="O(n^2)">。</p><p>空间复杂度：𝑂(𝑛2)<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="O(n^2)">。</p><blockquote><p>[!NOTE]</p><p>邻接矩阵只适用于<strong>没有重边</strong>（或重边可以忽略）的情况。</p><p>其最显著的优点是可以 <strong>𝑂(1)<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="O(1)"> 查询一条边是否存在。</strong></p><p>由于邻接矩阵在<strong>稀疏图上效率很低</strong>（尤其是在点数较多的图上，空间无法承受），所以一般只会在稠密图上使用邻接矩阵。</p></blockquote>        <h2 id="高级阶段：邻接表"   >          <a href="#高级阶段：邻接表" class="heading-link"><i class="fas fa-link"></i></a><a href="#高级阶段：邻接表" class="headerlink" title="高级阶段：邻接表"></a>高级阶段：邻接表</h2>      <p>如果说邻接矩阵的问人方式，是问遍所有人你认不认识张三，那么邻接表的问人方式像是直接查看张三的通讯录，只看张三认识的人。我们只用把每个人的认识的人都存在他的通讯录下，就可以实现高效拆查询。<strong>这里我们仍然用到vector(太好用了！)</strong></p><p>直观的说大概是这样的。</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">vector&lt;vector&lt;<span class="type">int</span>&gt;&gt;adj;</span><br><span class="line"><span class="comment">//示例，顶点1认识2，3，顶点2认识4</span></span><br><span class="line">adj[<span class="number">1</span>]=&#123;<span class="number">2</span>,<span class="number">3</span>&#125;;</span><br><span class="line">adj[<span class="number">2</span>]=&#123;<span class="number">4</span>&#125;;</span><br><span class="line">adj[<span class="number">3</span>]=&#123;&#125;;</span><br></pre></td></tr></table></div></figure><p>那邻接表怎么dfs遍历，和构建邻接表呢</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> u)</span></span>&#123;</span><br><span class="line"><span class="keyword">if</span>(vis[u])<span class="keyword">return</span>;</span><br><span class="line">vis[u]=<span class="literal">true</span>;</span><br><span class="line"><span class="comment">//直接访问u的邻居链表</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> v:adj[u])&#123;</span><br><span class="line">        <span class="keyword">if</span>(!vis[v])&#123;</span><br><span class="line">            <span class="built_in">dfs</span>(v);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">1</span>;i&lt;=m;i++)&#123;</span><br><span class="line">    <span class="type">int</span> u,v;</span><br><span class="line">    cin &gt;&gt;u&gt;&gt;v;</span><br><span class="line">    adj[u],<span class="built_in">push_back</span>(v);<span class="comment">//只在u的列表中添加v</span></span><br><span class="line">    <span class="comment">//注意：有向图不添加adj[v].push_back(u)</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>好的，附上完整代码</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;vector&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> n, m;</span><br><span class="line">vector&lt;vector&lt;<span class="type">int</span>&gt;&gt; adj;  <span class="comment">// 邻接表</span></span><br><span class="line">vector&lt;<span class="type">bool</span>&gt; vis;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> u)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (vis[u]) <span class="keyword">return</span>;</span><br><span class="line">    vis[u] = <span class="literal">true</span>;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 邻接表遍历：直接访问u的所有邻居</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> v : adj[u]) &#123;        <span class="comment">// 遍历u的邻居列表</span></span><br><span class="line">        <span class="keyword">if</span> (!vis[v]) &#123;</span><br><span class="line">            <span class="built_in">dfs</span>(v);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    cin &gt;&gt; n &gt;&gt; m;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 初始化：n+1个空列表</span></span><br><span class="line">    adj.<span class="built_in">resize</span>(n + <span class="number">1</span>);</span><br><span class="line">    vis.<span class="built_in">resize</span>(n + <span class="number">1</span>, <span class="literal">false</span>);</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 构建邻接表</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= m; ++i) &#123;</span><br><span class="line">        <span class="type">int</span> u, v;</span><br><span class="line">        cin &gt;&gt; u &gt;&gt; v;</span><br><span class="line">        adj[u].<span class="built_in">push_back</span>(v);  <span class="comment">// 只在u的列表中添加v</span></span><br><span class="line">        <span class="comment">// 注意：有向图，不添加adj[v].push_back(u)</span></span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="type">int</span> count = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; ++i) &#123;</span><br><span class="line">        <span class="keyword">if</span> (!vis[i]) &#123;</span><br><span class="line">            count++;</span><br><span class="line">            <span class="built_in">dfs</span>(i);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;有向图连通分量数量: &quot;</span> &lt;&lt; count &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>当然，这个简单的问题其实不能很好的体现邻接表的作用。（后面会补上完整邻接表板子）</p><p><strong>复杂度</strong></p><p>查询是否存在 𝑢<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="u"> 到 𝑣<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="v"> 的边：𝑂(𝑑+(𝑢))<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="O(d^+(u))">（如果事先进行了排序就可以使用 <span class="exturl"><a class="exturl__link"   href="https://oi-wiki.org/basic/binary/" >二分查找</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span> 做到 𝑂(log⁡(𝑑+(𝑢)))<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="O(\log(d^+(u)))">）。</p><p>遍历点 𝑢<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="u">的所有出边：𝑂(𝑑+(𝑢))<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="O(d^+(u))">。</p><p>遍历整张图：𝑂(𝑛 +𝑚)<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="O(n+m)">。</p><p>空间复杂度：𝑂(𝑚)<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="O(m)">。</p><p><strong>应用</strong></p><p><strong>存各种图都很适合</strong>，除非有特殊需求（如需要快速查询一条边是否存在，且点数较少，可以使用邻接矩阵）。</p><p>尤其适用于需要<strong>对一个点的所有出边进行排序的场合</strong>。</p>        <h2 id="同样高级的阶段：链式前向星"   >          <a href="#同样高级的阶段：链式前向星" class="heading-link"><i class="fas fa-link"></i></a><a href="#同样高级的阶段：链式前向星" class="headerlink" title="同样高级的阶段：链式前向星"></a>同样高级的阶段：链式前向星</h2>      <p>传统邻接表其实有一个很明显的问题，每个顶点都有一个vector。所以内存不连续，缓存不友好。</p><p>那么聪明的先人就发明出了链式前向星算法！</p><p><strong>用数组模拟链表，所有边存储在一个大数组中</strong></p><p>数据结构设计如下</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;cstring&gt;</span>  <span class="comment">// for memset</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> MAXN = <span class="number">100010</span>;  <span class="comment">// 最大顶点数</span></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> MAXM = <span class="number">200010</span>;  <span class="comment">// 最大边数（无向图要×2）</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 链式前向星的三要素</span></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">Edge</span>&#123;</span><br><span class="line">    <span class="type">int</span> to; <span class="comment">//边的终点</span></span><br><span class="line">    <span class="type">int</span> next; <span class="comment">//下一条边的索引</span></span><br><span class="line">    <span class="comment">// int weight; 边的权重（可选）</span></span><br><span class="line">&#125;edge[MAXM]; <span class="comment">//边数组</span></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> head[MAXN]; <span class="comment">//head[u],顶点u的第一条边在edge数组中的索引</span></span><br><span class="line"><span class="type">int</span> cnt=<span class="number">0</span>;<span class="comment">//边计数器，当前边的数量</span></span><br></pre></td></tr></table></div></figure><p>添加边的函数</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">addedge</span><span class="params">(<span class="type">int</span> u,<span class="type">int</span> v)</span></span>&#123;</span><br><span class="line">    edge[++cnt].to=v;<span class="comment">//新边的终点是u</span></span><br><span class="line">    edge[cnt].next=head[u];<span class="comment">//新边的下一条边u是原来的第一条边</span></span><br><span class="line">    head[u]=cnt;<span class="comment">//u的第一条边更新为新边</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>看不懂其实很正常，举个例子会好很多，假设我要依次添加边</p><p>1-&gt;2 ,1-&gt;3, 2-&gt;4</p><p><strong>添加1-2</strong></p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">初始化：head[1]=0,cnt=0</span><br><span class="line"> 添加边1-&gt;2</span><br><span class="line"> edge[1].to=2</span><br><span class="line"> edge[1].next=head[1]=0</span><br><span class="line"> head[1]=1</span><br><span class="line"> </span><br><span class="line"> 结果：head[1]-&gt;edge[1](to=2,next=0)</span><br></pre></td></tr></table></div></figure><p><strong>添加边1-3</strong></p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">edge[2].to=3</span><br><span class="line">edge[2].next=head[1]=1</span><br><span class="line">head[1]=2</span><br><span class="line"></span><br><span class="line">结果：</span><br><span class="line">head[1]-&gt;edge[2](to=3,next=1)-&gt;edge[1](to=2,next=0)-&gt;null</span><br></pre></td></tr></table></div></figure><p><strong>添加边2-&gt;4</strong></p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">edge[3].to = 4</span><br><span class="line">edge[3].next = head[2] = 0</span><br><span class="line">head[2] = 3</span><br><span class="line"></span><br><span class="line">结果:</span><br><span class="line">head[1] → edge[2] → edge[1] → NULL</span><br><span class="line">head[2] → edge[3] → NULL</span><br></pre></td></tr></table></div></figure><p><strong>遍历方式与过程解析</strong></p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 遍历u的所有邻居</span></span><br><span class="line"><span class="keyword">for</span> (<span class="type">int</span> i = head[u]; i != <span class="number">0</span>; i = edge[i].next) &#123;</span><br><span class="line">    <span class="type">int</span> v = edge[i].to;  <span class="comment">// 邻居顶点v</span></span><br><span class="line">    <span class="comment">// 处理v...</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">以顶点<span class="number">1</span>为例</span><br><span class="line">head[<span class="number">1</span>] = <span class="number">2</span></span><br><span class="line">第一次循环: i=<span class="number">2</span>, v=edge[<span class="number">2</span>].to=<span class="number">3</span></span><br><span class="line">第二次循环: i=edge[<span class="number">2</span>].next=<span class="number">1</span>, v=edge[<span class="number">1</span>].to=<span class="number">2</span>  </span><br><span class="line">第三次循环: i=edge[<span class="number">1</span>].next=<span class="number">0</span>, 结束</span><br></pre></td></tr></table></div></figure><p>完整代码如下</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;cstring&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> MAXN = <span class="number">100010</span>;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> MAXM = <span class="number">200010</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">Edge</span> &#123;</span><br><span class="line">    <span class="type">int</span> to;</span><br><span class="line">    <span class="type">int</span> next;</span><br><span class="line">    <span class="comment">// int weight;  // 如果需要边权</span></span><br><span class="line">&#125; edge[MAXM];</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> head[MAXN];</span><br><span class="line"><span class="type">int</span> cnt = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 初始化</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">init</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="built_in">memset</span>(head, <span class="number">0</span>, <span class="built_in">sizeof</span>(head));  <span class="comment">// 初始化为0</span></span><br><span class="line">    cnt = <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 添加边</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">addEdge</span><span class="params">(<span class="type">int</span> u, <span class="type">int</span> v)</span> </span>&#123;</span><br><span class="line">    edge[++cnt].to = v;</span><br><span class="line">    edge[cnt].next = head[u];</span><br><span class="line">    head[u] = cnt;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 添加带权边</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">addEdge</span><span class="params">(<span class="type">int</span> u, <span class="type">int</span> v, <span class="type">int</span> w)</span> </span>&#123;</span><br><span class="line">    edge[++cnt].to = v;</span><br><span class="line">    <span class="comment">// edge[cnt].weight = w;</span></span><br><span class="line">    edge[cnt].next = head[u];</span><br><span class="line">    head[u] = cnt;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// DFS遍历</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> u, <span class="type">bool</span> visited[])</span> </span>&#123;</span><br><span class="line">    visited[u] = <span class="literal">true</span>;</span><br><span class="line">    cout &lt;&lt; u &lt;&lt; <span class="string">&quot; &quot;</span>;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = head[u]; i != <span class="number">0</span>; i = edge[i].next) &#123;</span><br><span class="line">        <span class="type">int</span> v = edge[i].to;</span><br><span class="line">        <span class="keyword">if</span> (!visited[v]) &#123;</span><br><span class="line">            <span class="built_in">dfs</span>(v, visited);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 打印图的邻接关系</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">printGraph</span><span class="params">(<span class="type">int</span> n)</span> </span>&#123;</span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;链式前向星表示的图:&quot;</span> &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> u = <span class="number">1</span>; u &lt;= n; u++) &#123;</span><br><span class="line">        cout &lt;&lt; u &lt;&lt; <span class="string">&quot;: &quot;</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = head[u]; i != <span class="number">0</span>; i = edge[i].next) &#123;</span><br><span class="line">            cout &lt;&lt; edge[i].to &lt;&lt; <span class="string">&quot; &quot;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        cout &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="built_in">init</span>();</span><br><span class="line">    </span><br><span class="line">    <span class="type">int</span> n = <span class="number">5</span>;</span><br><span class="line">    <span class="comment">// 添加边: 1→2, 1→3, 2→4, 3→4, 4→5</span></span><br><span class="line">    <span class="built_in">addEdge</span>(<span class="number">1</span>, <span class="number">2</span>);</span><br><span class="line">    <span class="built_in">addEdge</span>(<span class="number">1</span>, <span class="number">3</span>);</span><br><span class="line">    <span class="built_in">addEdge</span>(<span class="number">2</span>, <span class="number">4</span>);</span><br><span class="line">    <span class="built_in">addEdge</span>(<span class="number">3</span>, <span class="number">4</span>);</span><br><span class="line">    <span class="built_in">addEdge</span>(<span class="number">4</span>, <span class="number">5</span>);</span><br><span class="line">    </span><br><span class="line">    <span class="built_in">printGraph</span>(n);</span><br><span class="line">    </span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;DFS遍历(从1开始): &quot;</span>;</span><br><span class="line">    <span class="type">bool</span> visited[MAXN] = &#123;<span class="literal">false</span>&#125;;</span><br><span class="line">    <span class="built_in">dfs</span>(<span class="number">1</span>, visited);</span><br><span class="line">    cout &lt;&lt; endl;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h5 id="应用"   >          <a href="#应用" class="heading-link"><i class="fas fa-link"></i></a><a href="#应用" class="headerlink" title="应用"></a>应用</h5>      <p>存各种图都很适合，但不能快速查询一条边是否存在，也不能方便地对一个点的出边进行排序。</p><p>优点是边是带编号的，有时会非常有用，而且如果 <code>cnt</code> 的初始值为奇数，存双向边时 <code>i ^ 1</code> 即是 <code>i</code> 的反边（常用于 <span class="exturl"><a class="exturl__link"   href="https://oi-wiki.org/graph/flow/" >网络流</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span>）。</p>        <h1 id="dfs"   >          <a href="#dfs" class="heading-link"><i class="fas fa-link"></i></a><a href="#dfs" class="headerlink" title="dfs"></a>dfs</h1>      <p>DFS 全称是 <span class="exturl"><a class="exturl__link"   href="https://en.wikipedia.org/wiki/Depth-first_search" >Depth First Search</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span>，中文名是深度优先搜索，是一种用于遍历或搜索树或图的算法。所谓深度优先，就是说每次都尝试向更深的节点走。</p><p>DFS 最显著的特征在于其 <strong>递归调用自身</strong>。同时与 BFS 类似，DFS 会对其访问过的点打上访问标记，在遍历图时跳过已打过标记的点，以确保 <strong>每个点仅访问一次</strong>。符合以上两条规则的函数，便是广义上的 DFS。</p><p>具体地说，DFS 大致结构如下</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">DFS(v) // v 可以是图中的一个顶点，也可以是抽象的概念，如 dp 状态等。</span><br><span class="line">  在 v 上打访问标记</span><br><span class="line">  for u in v 的相邻节点</span><br><span class="line">    if u 没有打过访问标记 then</span><br><span class="line">      DFS(u)</span><br><span class="line">    end</span><br><span class="line">  end</span><br><span class="line">end</span><br></pre></td></tr></table></div></figure><p>我们可以递归实现dfs，也可以栈。</p>        <h2 id="递归实现"   >          <a href="#递归实现" class="heading-link"><i class="fas fa-link"></i></a><a href="#递归实现" class="headerlink" title="递归实现"></a>递归实现</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">vector&lt;vector&lt;<span class="type">int</span>&gt;&gt; adj;  <span class="comment">// 邻接表</span></span><br><span class="line">vector&lt;<span class="type">bool</span>&gt; vis;         <span class="comment">// 记录节点是否已经遍历</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">const</span> <span class="type">int</span> u)</span> </span>&#123;</span><br><span class="line">  vis[u] = <span class="literal">true</span>;</span><br><span class="line">  <span class="keyword">for</span> (<span class="type">int</span> v : adj[u])</span><br><span class="line">    <span class="keyword">if</span> (!vis[v]) <span class="built_in">dfs</span>(v)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="栈实现"   >          <a href="#栈实现" class="heading-link"><i class="fas fa-link"></i></a><a href="#栈实现" class="headerlink" title="栈实现"></a>栈实现</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">vector&lt;vector&lt;<span class="type">int</span>&gt;&gt; adj;  <span class="comment">// 邻接表</span></span><br><span class="line">vector&lt;<span class="type">bool</span>&gt; vis;         <span class="comment">// 记录节点是否已经遍历</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> s)</span> </span>&#123;</span><br><span class="line">  stack&lt;<span class="type">int</span>&gt; st;</span><br><span class="line">  st.<span class="built_in">push</span>(s);</span><br><span class="line">  vis[s] = <span class="literal">true</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">while</span> (!st.<span class="built_in">empty</span>()) &#123;<span class="comment">//当栈非空</span></span><br><span class="line">    <span class="type">int</span> u = st.<span class="built_in">top</span>();<span class="comment">//存储栈顶元素</span></span><br><span class="line">    st.<span class="built_in">pop</span>();<span class="comment">//弹出栈顶元素</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> v : adj[u]) &#123;</span><br><span class="line">      <span class="keyword">if</span> (!vis[v]) &#123;<span class="comment">//如果没被访问过</span></span><br><span class="line">        vis[v] = <span class="literal">true</span>;  <span class="comment">// 确保栈里没有重复元素</span></span><br><span class="line">        st.<span class="built_in">push</span>(v);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>（以后单开一篇文讲dfs,bfs实战，这里不做重点）</p>        <h1 id="bfs"   >          <a href="#bfs" class="heading-link"><i class="fas fa-link"></i></a><a href="#bfs" class="headerlink" title="bfs"></a>bfs</h1>      <p>BFS 全称是 <span class="exturl"><a class="exturl__link"   href="https://en.wikipedia.org/wiki/Breadth-first_search" >Breadth First Search</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span>，中文名是宽度优先搜索，也叫广度优先搜索。</p><p>是图上最基础、最重要的搜索算法之一。</p><p>所谓宽度优先。就是每次都尝试访问同一层的节点。 如果同一层都访问完了，再访问下一层。</p><p>这样做的结果是，BFS 算法找到的路径是从起点开始的 <strong>最短</strong> 合法路径。换言之，这条路径所包含的边数最小。</p><p>在 BFS 结束时，每个节点都是通过从起点到该点的最短路径访问的。</p>        <h3 id="数据结构说明："   >          <a href="#数据结构说明：" class="heading-link"><i class="fas fa-link"></i></a><a href="#数据结构说明：" class="headerlink" title="数据结构说明："></a>数据结构说明：</h3>      <ul><li><code>Q</code>：队列，用于BFS遍历</li><li><code>vis[]</code>：标记数组，记录节点是否被访问过</li><li><code>d[]</code>：距离数组，记录每个节点到起点的最短距离</li><li><code>p[]</code>：前驱数组，记录每个节点在最短路径上的前一个节点</li><li><code>head[]</code>和<code>e[]</code>：图的邻接表存储结构</li></ul>        <h3 id="BFS执行流程："   >          <a href="#BFS执行流程：" class="heading-link"><i class="fas fa-link"></i></a><a href="#BFS执行流程：" class="headerlink" title="BFS执行流程："></a>BFS执行流程：</h3>      <ol><li><strong>初始化</strong>：清空队列，将起点加入队列并标记</li><li><strong>循环处理</strong>：从队列中取出节点，遍历其所有未访问的邻居</li><li><strong>更新信息</strong>：记录邻居节点的距离和前驱节点</li><li><strong>继续扩展</strong>：将邻居节点加入队列等待处理</li></ol>        <h3 id="路径还原原理："   >          <a href="#路径还原原理：" class="heading-link"><i class="fas fa-link"></i></a><a href="#路径还原原理：" class="headerlink" title="路径还原原理："></a>路径还原原理：</h3>      <p>利用BFS树的性质，每个节点的前驱节点<code>p[v]</code>记录了到达该节点的最短路径上的前一个节点。通过从目标节点不断回溯前驱节点，就能得到完整的路径。</p>        <h3 id="特点："   >          <a href="#特点：" class="heading-link"><i class="fas fa-link"></i></a><a href="#特点：" class="headerlink" title="特点："></a>特点：</h3>      <ul><li><strong>最短路径</strong>：BFS保证找到的是从起点到各点的最短路径（边权为1时）</li><li><strong>层次遍历</strong>：按距离起点的层次顺序遍历节点</li><li><strong>时间复杂度</strong>：O(V+E)，其中V是节点数，E是边数</li></ul><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 广度优先搜索（BFS）函数，从起点u开始遍历</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">bfs</span><span class="params">(<span class="type">int</span> u)</span> </span>&#123;</span><br><span class="line">  <span class="keyword">while</span> (!Q.<span class="built_in">empty</span>()) Q.<span class="built_in">pop</span>();  <span class="comment">// 清空队列，确保队列为空</span></span><br><span class="line">  Q.<span class="built_in">push</span>(u);                   <span class="comment">// 将起点加入队列</span></span><br><span class="line">  vis[u] = <span class="number">1</span>;                  <span class="comment">// 标记起点为已访问</span></span><br><span class="line">  d[u] = <span class="number">0</span>;                    <span class="comment">// 起点到自身的距离为0</span></span><br><span class="line">  p[u] = <span class="number">-1</span>;                   <span class="comment">// 起点的前驱节点设为-1（表示无前驱）</span></span><br><span class="line">  </span><br><span class="line">  <span class="keyword">while</span> (!Q.<span class="built_in">empty</span>()) &#123;         <span class="comment">// 当队列不为空时继续搜索</span></span><br><span class="line">    u = Q.<span class="built_in">front</span>();             <span class="comment">// 取出队首节点</span></span><br><span class="line">    Q.<span class="built_in">pop</span>();                   <span class="comment">// 弹出队首节点</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 遍历当前节点u的所有邻居节点</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = head[u]; i; i = e[i].nxt) &#123;</span><br><span class="line">      <span class="comment">// 如果邻居节点未被访问过</span></span><br><span class="line">      <span class="keyword">if</span> (!vis[e[i].to]) &#123;</span><br><span class="line">        Q.<span class="built_in">push</span>(e[i].to);       <span class="comment">// 将邻居节点加入队列</span></span><br><span class="line">        vis[e[i].to] = <span class="number">1</span>;      <span class="comment">// 标记邻居节点为已访问</span></span><br><span class="line">        d[e[i].to] = d[u] + <span class="number">1</span>; <span class="comment">// 记录邻居节点到起点的距离（当前节点距离+1）</span></span><br><span class="line">        p[e[i].to] = u;        <span class="comment">// 记录邻居节点的前驱节点为当前节点u</span></span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 还原从起点到节点x的最短路径</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">restore</span><span class="params">(<span class="type">int</span> x)</span> </span>&#123;</span><br><span class="line">  vector&lt;<span class="type">int</span>&gt; res;             <span class="comment">// 存储路径的容器</span></span><br><span class="line">  </span><br><span class="line">  <span class="comment">// 从目标节点x开始，沿着前驱指针回溯到起点</span></span><br><span class="line">  <span class="keyword">for</span> (<span class="type">int</span> v = x; v != <span class="number">-1</span>; v = p[v]) &#123;</span><br><span class="line">    res.<span class="built_in">push_back</span>(v);          <span class="comment">// 将路径上的节点加入容器</span></span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  std::<span class="built_in">reverse</span>(res.<span class="built_in">begin</span>(), res.<span class="built_in">end</span>());  <span class="comment">// 反转容器，使路径从起点到终点</span></span><br><span class="line">  </span><br><span class="line">  <span class="comment">// 输出路径</span></span><br><span class="line">  <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; res.<span class="built_in">size</span>(); ++i) </span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;%d&quot;</span>, res[i]);</span><br><span class="line">  <span class="built_in">puts</span>(<span class="string">&quot;&quot;</span>);                    <span class="comment">// 换行</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h3 id="应用-1"   >          <a href="#应用-1" class="heading-link"><i class="fas fa-link"></i></a><a href="#应用-1" class="headerlink" title="应用"></a>应用</h3>      <ul><li>在一个无权图上求从起点到其他所有点的<strong>最短路径。</strong></li><li>在 𝑂(𝑛 +𝑚)<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="O(n+m)"> 时间内求出<strong>所有连通块</strong>。（我们只需要从每个没有被访问过的节点开始做 BFS，显然每次 BFS 会走完一个连通块)</li><li>如果把一个游戏的动作看做是状态图上的一条边（一个转移），那么 BFS 可以用来找到在游戏中从一个状态到达另一个状态所需要的最小步骤。</li><li>在一个<strong>有向无权图中找最小环</strong>。（从每个点开始 BFS，在我们即将抵达一个之前访问过的点开始的时候，就知道遇到了一个环。图的最小环是每次 BFS 得到的最小环的平均值。）</li><li>找到一定<strong>在 (𝑎,𝑏)<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="(a, b)"> 最短路上的边</strong>。（分别从 a 和 b 进行 BFS，得到两个 d 数组。之后对每一条边 (𝑢,𝑣)<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="(u, v)">，如果 𝑑𝑎[𝑢] +1 +𝑑𝑏[𝑣] &#x3D;𝑑𝑎[𝑏]<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="d_a[u]+1+d_b[v]&#x3D;d_a[b]">，则说明该边在最短路上)</li><li>找到一<strong>定在 (𝑎,𝑏)<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="(a, b)"> 最短路上的点</strong>。（分别从 a 和 b 进行 BFS，得到两个 d 数组。之后对每一个点 v，如果 𝑑𝑎[𝑣] +𝑑𝑏[𝑣] &#x3D;𝑑𝑎[𝑏]<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="d_a[v]+d_b[v]&#x3D;d_a[b]">，则说明该点在某条最短路上）</li><li>找到一条长度为偶数的最短路。（我们需要一个构造一个新图，把每个点拆成两个新点，原图的边 (𝑢,𝑣)<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="(u, v)"> 变成 ((𝑢,0),(𝑣,1))<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="((u, 0), (v, 1))"> 和 ((𝑢,1),(𝑣,0))<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="((u, 1), (v, 0))">。对新图做 BFS，(𝑠,0)<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="(s, 0)"> 和 (𝑡,0)<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="(t, 0)"> 之间的最短路即为所求）</li><li>在一个边权为 0&#x2F;1 的图上求最短路，见下方双端队列 BFS。</li></ul>]]></content>
      
      
      <categories>
          
          <category> 算法 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> 算法 </tag>
            
            <tag> acm </tag>
            
            <tag> 数据结构 </tag>
            
            <tag> 图论 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>acm随笔</title>
      <link href="/2025/10/31/acm%E5%B0%8F%E5%BF%83%E5%BE%97/"/>
      <url>/2025/10/31/acm%E5%B0%8F%E5%BF%83%E5%BE%97/</url>
      
        <content type="html"><![CDATA[<p>遇到异或，总归关于数学，先将有关于<strong>异或的式子以及性质全部列出来</strong>，根据题目选取有用的</p><ul><li><p>a+b&#x3D;（a^b）+  2 * （a&amp;b）</p></li><li><p>(a&amp;b）&amp;（a^b）&#x3D; 0</p></li><li><p>a^a&#x3D;0</p></li><li><p>x&#x3D;a^a^x</p></li><li><p>a^0&#x3D;a</p></li><li><p>一个序列异或起来等于0，将序列分成两个集合，不管怎么分，两个集合内部异或起来得到的结果肯定相等</p></li><li><p>一个序列的<strong>异或和一定小于等于数值和</strong>（异或的本质是二进制下的不进位加法，相比起进位的普通加法，所得的结果当然会较小）&#x3D;&#x3D;&gt;a^b&lt;&#x3D;a+b</p></li><li><p><strong>a^b&gt;&#x3D;a-b</strong></p></li><li><p>一个序列的<strong>数值和</strong> 和 <strong>异或和</strong>  <strong>奇偶性</strong>相同</p></li><li><p>如果a^b已知&#x3D;x或者a&amp;b已知&#x3D;y，那么要确定a和b，只要进行分配1即可</p></li></ul><p>然后如果都没用到的话，大概是单独考虑每一位</p><blockquote><p>x%p&#x3D;y,则x&#x3D;k<em>p+y<br>^为异或<br>所以g^(p-1)&#x3D;k</em>p+1<br> g&#x3D;(k*p+1)^(p-1)</p></blockquote>]]></content>
      
      
      <categories>
          
          <category> 算法 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 算法 </tag>
            
            <tag> acm </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>numpy入门</title>
      <link href="/2025/09/29/numpy/"/>
      <url>/2025/09/29/numpy/</url>
      
        <content type="html"><![CDATA[<p>本文主要参考<span class="exturl"><a class="exturl__link"   href="https://www.runoob.com/" >菜鸟教程</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span>和b站莫烦老师的视频，学习过程中发现其实很多部分讲的<strong>过于笼统</strong>，内容学习顺序不太妥当，有些内容<strong>无法直接理解</strong>。故自己调整了下学习顺序，对一些内容进行了扩展补充，对一些内容则进行了删改（非常少，基本都涵盖了）。如果你也<strong>刚入门</strong>，可以看看这篇文章，但是如果你已经是大牛，便不用浪费时间了</p>        <h2 id="1-什么是numpy"   >          <a href="#1-什么是numpy" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-什么是numpy" class="headerlink" title="1.什么是numpy?"></a>1.什么是numpy?</h2>      <p><code>NumPy</code>(Numerical Python)是<strong>Python</strong>语言的一个<strong>扩展程序库</strong>，支持大量的<strong>维度数组</strong>和<strong>矩阵运算</strong>。也针对数组运算提供大量的<strong>数学函数库</strong>。</p><p>它的运行速度非常快，主要用于数组计算，包含：</p><ul><li>强大的N维数组对象 ndarray</li><li>广播函数功能</li><li>整合c&#x2F;c++&#x2F;Fortran代码的工具</li><li>线性代数，傅里叶变换，随机数生成等功能</li></ul><p>（NumPy 通常与 SciPy（Scientific Python）和 Matplotlib（绘图库）一起使用， 这种组合广泛用于替代 MatLab，是一个强大的科学计算环境，有助于我们通过 Python 学习数据科学或者机器学习。）</p>        <h2 id="2-如何安装numpy"   >          <a href="#2-如何安装numpy" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-如何安装numpy" class="headerlink" title="2.如何安装numpy?"></a>2.如何安装numpy?</h2>      <p><span class="exturl"><a class="exturl__link"   href="https://www.runoob.com/numpy/numpy-install.html" >NumPy 安装 | 菜鸟教程</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p><p>前人所述备矣~依旧搬运</p>        <h2 id="3-矩阵的实现（array）"   >          <a href="#3-矩阵的实现（array）" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-矩阵的实现（array）" class="headerlink" title="3.矩阵的实现（array）"></a>3.矩阵的实现（array）</h2>      <p>通过<code>array（）</code>我们可以实现矩阵的创建，我们需要在括号中填入<strong>列表形式</strong>的参数。</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">a=np.array([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>])</span><br><span class="line"><span class="built_in">print</span>(a)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">type</span>(a))</span><br><span class="line"></span><br><span class="line"><span class="comment">#输出结果</span></span><br><span class="line">[<span class="number">1</span> <span class="number">2</span> <span class="number">3</span>]</span><br><span class="line">&lt;<span class="keyword">class</span> <span class="string">&#x27;numpy.ndarray&#x27;</span>&gt;</span><br></pre></td></tr></table></div></figure><p>它和列表的一个差别是，<strong>没有逗号</strong>（似乎显而易见）</p><p>而当我们尝试去输出数据类型，会发现一个陌生的字符串“numpy.ndarray”</p>        <h4 id="什么是ndarray"   >          <a href="#什么是ndarray" class="heading-link"><i class="fas fa-link"></i></a><a href="#什么是ndarray" class="headerlink" title="什么是ndarray?"></a>什么是ndarray?</h4>      <p>NumPy 最重要的一个特点是其 <strong>N 维数组对象 ndarray</strong>，它是一系列同类型数据的集合，以 0 下标为开始进行集合中元素的索引。</p><p>ndarray 对象是用于<strong>存放同类型元素</strong>的多维数组。</p><p>ndarray 中的每个元素在内存中都有<strong>相同存储大小的区域</strong>。</p><p>ndarray 内部由以下内容组成：</p><ul><li>一个指向数据（内存或内存映射文件中的一块数据）的指针。</li><li>数据类型或 dtype，描述在数组中的固定大小值的格子。</li><li>一个表示数组形状（shape）的元组，表示各维度大小的元组。</li><li>一个跨度元组（stride），其中的整数指的是为了前进到当前维度下一个元素需要”跨过”的字节数。</li></ul><p><img src="/../images/image-20250929093614818.png" alt="image-20250929093614818"></p><p>创建一个 ndarray 只需调用 NumPy 的 array 函数即可：</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">numpy.array(<span class="built_in">object</span>, dtype = <span class="literal">None</span>, copy = <span class="literal">True</span>, order = <span class="literal">None</span>, subok = <span class="literal">False</span>, ndmin = <span class="number">0</span>)</span><br></pre></td></tr></table></div></figure><p>这些参数中只有object是必须传入的。下附参数说明：</p><div class="table-container"><table><thead><tr><th align="left">名称</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">object</td><td align="left"><strong>数组</strong>或嵌套的数列</td></tr><tr><td align="left">dtype</td><td align="left">数组元素的<strong>数据类型</strong>，可选</td></tr><tr><td align="left">copy</td><td align="left">对象是否需要<strong>复制</strong>，可选</td></tr><tr><td align="left">order</td><td align="left"><strong>创建数组的样式</strong>，C为行方向，F为列方向，A为任意方向（默认）</td></tr><tr><td align="left">subok</td><td align="left">默认返回一个与基类类型一致的数组</td></tr><tr><td align="left">ndmin</td><td align="left">指定生成数组的<strong>最小维度</strong></td></tr></tbody></table></div><p>下面我们来实际演示这些参数（只演示比较重要的，如果你感兴趣可以自己搜索）。</p><p>一开始我们就演示了一维数组的创立，二维也是同理</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 多于一个维度  </span></span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np </span><br><span class="line">a = np.array([[<span class="number">1</span>,  <span class="number">2</span>],  [<span class="number">3</span>,  <span class="number">4</span>]])  <span class="comment">#注意！不能写成（[1,2],[3,4]）</span></span><br><span class="line"><span class="built_in">print</span> (a)</span><br><span class="line"><span class="comment">#输出结果如下</span></span><br><span class="line">[[<span class="number">1</span>  <span class="number">2</span>] </span><br><span class="line"> [<span class="number">3</span>  <span class="number">4</span>]]</span><br></pre></td></tr></table></div></figure>        <h4 id="ndmin-最小维度"   >          <a href="#ndmin-最小维度" class="heading-link"><i class="fas fa-link"></i></a><a href="#ndmin-最小维度" class="headerlink" title="ndmin(最小维度)"></a>ndmin(最小维度)</h4>      <p>什么是最小维度？顾名思义就是你定义的这个矩阵最少是几维，那你可能会疑惑，要是我定义一个一维数组但是令ndmin&#x3D;2会怎么样呢？</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 最小维度  </span></span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np </span><br><span class="line">a = np.array([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>], ndmin =  <span class="number">2</span>)  </span><br><span class="line"><span class="built_in">print</span> (a)</span><br><span class="line"></span><br><span class="line"><span class="comment">#输出如下</span></span><br><span class="line">[[<span class="number">1</span> <span class="number">2</span> <span class="number">3</span> <span class="number">4</span> <span class="number">5</span>]]</span><br></pre></td></tr></table></div></figure><p>可以观察到这是有两对[]的。这就是ndmin&#x3D;2起到的效果。也就是说你改成三的话会有三对[]，少于三对会帮你自动补全[]，<strong>那如果多于三对呢？</strong></p><p>答案是什么都不会发生，因为一开始我们就说了这是<strong>最少</strong>。所以你维度再多也没关系。</p>        <h4 id="detype（数据类型）"   >          <a href="#detype（数据类型）" class="heading-link"><i class="fas fa-link"></i></a><a href="#detype（数据类型）" class="headerlink" title="detype（数据类型）"></a>detype（数据类型）</h4>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">a =np.array([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],dtype=<span class="built_in">complex</span>)</span><br><span class="line"><span class="built_in">print</span>(a)</span><br><span class="line"><span class="comment">#输出结果</span></span><br><span class="line">[<span class="number">1.</span>+<span class="number">0.j</span> <span class="number">2.</span>+<span class="number">0.j</span> <span class="number">3</span>+<span class="number">0.j</span>]</span><br></pre></td></tr></table></div></figure><p>代码可以看到我们传给dtype的参数是complex，结合输出我们可以看出这是<strong>复数</strong>的意思。那么numpy有哪些数据类型呢？numpy 支持的数据类型比 Python 内置的类型要多很多，<strong>基本上可以和 C 语言的数据类型对应上</strong>，其中部分类型对应为 Python 内置的类型。下表列举了常用 NumPy 基本类型。（看看就行不用硬背）</p><div class="table-container"><table><thead><tr><th align="left">名称</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">bool_</td><td align="left">布尔型数据类型（True 或者 False）</td></tr><tr><td align="left">int_</td><td align="left">默认的整数类型（类似于 C 语言中的 long，int32 或 int64）</td></tr><tr><td align="left">intc</td><td align="left">与 C 的 int 类型一样，一般是 int32 或 int 64</td></tr><tr><td align="left">intp</td><td align="left">用于索引的整数类型（类似于 C 的 ssize_t，一般情况下仍然是 int32 或 int64）</td></tr><tr><td align="left">int8</td><td align="left">字节（-128 to 127）</td></tr><tr><td align="left">int16</td><td align="left">整数（-32768 to 32767）</td></tr><tr><td align="left">int32</td><td align="left">整数（-2147483648 to 2147483647）</td></tr><tr><td align="left">int64</td><td align="left">整数（-9223372036854775808 to 9223372036854775807）</td></tr><tr><td align="left">uint8</td><td align="left">无符号整数（0 to 255）</td></tr><tr><td align="left">uint16</td><td align="left">无符号整数（0 to 65535）</td></tr><tr><td align="left">uint32</td><td align="left">无符号整数（0 to 4294967295）</td></tr><tr><td align="left">uint64</td><td align="left">无符号整数（0 to 18446744073709551615）</td></tr><tr><td align="left">float_</td><td align="left">float64 类型的简写</td></tr><tr><td align="left">float16</td><td align="left">半精度浮点数，包括：1 个符号位，5 个指数位，10 个尾数位</td></tr><tr><td align="left">float32</td><td align="left">单精度浮点数，包括：1 个符号位，8 个指数位，23 个尾数位</td></tr><tr><td align="left">float64</td><td align="left">双精度浮点数，包括：1 个符号位，11 个指数位，52 个尾数位</td></tr><tr><td align="left">complex_</td><td align="left">complex128 类型的简写，即 128 位复数</td></tr><tr><td align="left">complex64</td><td align="left">复数，表示双 32 位浮点数（实数部分和虚数部分）</td></tr><tr><td align="left">complex128</td><td align="left">复数，表示双 64 位浮点数（实数部分和虚数部分）</td></tr></tbody></table></div><p>我们用实例来理解一下</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="comment"># 使用标量类型</span></span><br><span class="line">dt = np.dtype(np.int32)</span><br><span class="line"><span class="built_in">print</span>(dt)</span><br><span class="line"><span class="comment">#输出结果</span></span><br><span class="line"><span class="built_in">int</span> <span class="number">32</span></span><br></pre></td></tr></table></div></figure><p>注意，# int8, int16, int32, int64 四种数据类型可以使用字符串 <strong>‘i1’, ‘i2’,’i4’,’i8’</strong> 代替，所以你看到这些参数不要疑惑，这只是它们的另一种表达方式</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">dt = np.dtype(<span class="string">&#x27;i4&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(dt)</span><br><span class="line"><span class="comment">#输出结果</span></span><br><span class="line"><span class="built_in">int</span> <span class="number">32</span></span><br></pre></td></tr></table></div></figure>        <h4 id="dtype创建结构化数据类型"   >          <a href="#dtype创建结构化数据类型" class="heading-link"><i class="fas fa-link"></i></a><a href="#dtype创建结构化数据类型" class="headerlink" title="dtype创建结构化数据类型"></a>dtype创建结构化数据类型</h4>      <p>NumPy的结构化数据类型（<code>dtype</code>）让你能在数组中处理像<strong>数据库表记录</strong>或<strong>C语言结构体</strong>这样的复合数据</p><p>创建结构化数据类型我们有四种方式</p><ul><li><strong>元组列表（最常用最推荐，其他的了解即可）</strong></li><li>逗号分隔字符串</li><li>字段参数字典</li><li>字段名称字典</li></ul><div class="table-container"><table><thead><tr><th align="left">方法</th><th align="left">语法示例</th><th align="left">特点说明</th></tr></thead><tbody><tr><td align="left"><strong>元组列表</strong></td><td align="left"><code>dtype = np.dtype([(&#39;name&#39;, &#39;U10&#39;), (&#39;age&#39;, &#39;i4&#39;), (&#39;weight&#39;, &#39;f4&#39;)])</code></td><td align="left">最常用且灵活的方式，直接指定字段名和数据类型。字段名若为空字符串 <code>&#39;&#39;</code>，会自动生成 <code>f0</code>, <code>f1</code>等默认名称。</td></tr><tr><td align="left"><strong>逗号分隔字符串</strong></td><td align="left"><code>dtype = np.dtype(&#39;i8, f4, S3&#39;)</code>或 <code>dtype = np.dtype(&#39;3int8, float32, (2,3)float64&#39;)</code></td><td align="left">写法简洁，适合快速定义。字段名默认为 <code>f0</code>, <code>f1</code>…。字符串中的数字可以定义数组形状，如<code>(2,3)float64</code>表示一个2x3的浮点数子数组。</td></tr><tr><td align="left"><strong>字段参数字典</strong></td><td align="left"><code>dtype = np.dtype(&#123;&#39;names&#39;: [&#39;col1&#39;, &#39;col2&#39;], &#39;formats&#39;: [&#39;i4&#39;, &#39;f4&#39;]&#125;)</code></td><td align="left">提供高级控制，可精确指定字节偏移量(<code>offsets</code>)、总字节大小(<code>itemsize</code>)等内存布局细节。</td></tr><tr><td align="left"><strong>字段名称字典</strong></td><td align="left"><code>dtype = np.dtype(&#123;&#39;col1&#39;: (&#39;i1&#39;, 0), &#39;col2&#39;: (&#39;f4&#39;, 1)&#125;)</code></td><td align="left"><strong>不推荐使用</strong>，因为在Python 3.6之前字典不保留字段顺序。</td></tr></tbody></table></div><p>我们来实例演示一下</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">dt = np.dtype([(<span class="string">&#x27;age&#x27;</span>,np.int8)])</span><br><span class="line">a = np.array([(<span class="number">10</span>,),(<span class="number">20</span>,),(<span class="number">30</span>,)],dtype=dt)</span><br><span class="line"><span class="built_in">print</span>(a)</span><br><span class="line"><span class="built_in">print</span>(a[<span class="string">&#x27;age&#x27;</span>])</span><br><span class="line"><span class="built_in">print</span>(a[<span class="number">0</span>][<span class="string">&#x27;age&#x27;</span>])</span><br><span class="line"></span><br><span class="line"><span class="comment">#输出结果</span></span><br><span class="line">[(<span class="number">10</span>,) (<span class="number">20</span>,) (<span class="number">30</span>,)]</span><br><span class="line">[<span class="number">10</span> <span class="number">20</span> <span class="number">30</span>]</span><br><span class="line"><span class="number">10</span></span><br></pre></td></tr></table></div></figure><ul><li><code>[(&#39;age&#39;, np.int8)]</code>是一个列表，其中包含一个元组，这个元组定义了一个字段。</li><li><code>&#39;age&#39;</code>是字段的名称，以后可以通过这个名字来访问数组中的这一”列”数据</li><li><code>np.int8</code>指定了这个字段的数据类型是8位整数（范围从-128到127），非常节省内存</li></ul><p>(是不是觉得和<strong>c的结构体</strong>非常相似呢)</p><p>我们再来看一个例子，下面的示例定义一个结构化数据类型 student，包含<strong>字符串字段 name</strong>，<strong>整数字段 age</strong>，及<strong>浮点字段 marks</strong>，并将这个 dtype 应用到 ndarray 对象。</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"> </span><br><span class="line">student = np.dtype([(<span class="string">&#x27;name&#x27;</span>,<span class="string">&#x27;S20&#x27;</span>), (<span class="string">&#x27;age&#x27;</span>, <span class="string">&#x27;i1&#x27;</span>), (<span class="string">&#x27;marks&#x27;</span>, <span class="string">&#x27;f4&#x27;</span>)]) </span><br><span class="line">a = np.array([(<span class="string">&#x27;abc&#x27;</span>, <span class="number">21</span>, <span class="number">50</span>),(<span class="string">&#x27;xyz&#x27;</span>, <span class="number">18</span>, <span class="number">75</span>)], dtype = student) </span><br><span class="line"><span class="built_in">print</span>(a)</span><br><span class="line"><span class="comment">#输出结果</span></span><br><span class="line">[(<span class="string">b&#x27;abc&#x27;</span>, <span class="number">21</span>, <span class="number">50.</span>) (<span class="string">b&#x27;xyz&#x27;</span>, <span class="number">18</span>, <span class="number">75.</span>)]</span><br></pre></td></tr></table></div></figure><p>可以看到abc的前面<strong>多了一个b</strong>，50的后面<strong>多了一个‘.’</strong>，这就是数据结构化的表现。</p><p>这个“.”我们可以理解，浮点数嘛，但是这个b怎么理解呢？</p><p>在Python 3中，<code>&#39;abc&#39;</code>这样的文本默认是Unicode<strong>字符串</strong>（<code>str</code>类型）。而<strong>字节串</strong>（<code>bytes</code>类型）用于表示原始的二进制数据或经过编码的文本（如UTF-8编码）。当NumPy使用 <code>&#39;S&#39;</code>类型（比如实例中的“s20”）时，它会将你提供的字符串转换为字节串进行存储。打印时，<strong>Python为了明确显示这是字节串而非普通字符串</strong>，就加上了 <code>b</code>前缀。附表供参考，依旧了解即可不需要背</p><div class="table-container"><table><thead><tr><th align="left">字符</th><th align="left">对应类型</th></tr></thead><tbody><tr><td align="left">b</td><td align="left">布尔型</td></tr><tr><td align="left">i</td><td align="left">(有符号) 整型</td></tr><tr><td align="left">u</td><td align="left">无符号整型 integer</td></tr><tr><td align="left">f</td><td align="left">浮点型</td></tr><tr><td align="left">c</td><td align="left">复数浮点型</td></tr><tr><td align="left">m</td><td align="left">timedelta（时间间隔）</td></tr><tr><td align="left">M</td><td align="left">datetime（日期时间）</td></tr><tr><td align="left">O</td><td align="left">(Python) 对象</td></tr><tr><td align="left">S, a</td><td align="left">(byte-)字符串</td></tr><tr><td align="left">U</td><td align="left">Unicode</td></tr><tr><td align="left">V</td><td align="left">原始数据 (void)</td></tr></tbody></table></div>        <h2 id="np-arange"   >          <a href="#np-arange" class="heading-link"><i class="fas fa-link"></i></a><a href="#np-arange" class="headerlink" title="np.arange"></a>np.arange</h2>      <p><code>np.arange</code>是 NumPy 中用于创建等差数列数组的重要函数。(可以设置dtype，不做演示)</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">a=np.arange(<span class="number">5</span>)</span><br><span class="line">b=np.arange(<span class="number">2</span>,<span class="number">7</span>)</span><br><span class="line">c=(<span class="number">2</span>,<span class="number">7</span>,<span class="number">2</span>)</span><br><span class="line"><span class="built_in">print</span>(a)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 输出：[0 1 2 3 4]</span></span><br><span class="line"><span class="comment">#[2 3 4 5 6]</span></span><br><span class="line"><span class="comment">#[2 4 6]</span></span><br></pre></td></tr></table></div></figure><p>你只传入一个参数时，NumPy会将其视为 <code>stop</code>，序列从 <code>0</code>开始，以 <code>1</code>为步长增长，直到<strong>小于</strong>这个值。</p><p>传入两个参数时，则是start和stop，步长默认1</p><p>传入三个参数时，<strong>指定 <code>start</code>, <code>stop</code>和 <code>step</code></strong>：这是最灵活的方式，可以完全控制序列。</p>        <h4 id="⚠️-重要注意事项与替代方案"   >          <a href="#⚠️-重要注意事项与替代方案" class="heading-link"><i class="fas fa-link"></i></a><a href="#⚠️-重要注意事项与替代方案" class="headerlink" title="⚠️ 重要注意事项与替代方案"></a>⚠️ 重要注意事项与替代方案</h4>      <ul><li><p>浮点精度问题：因为浮点数在计算机中表示不精确，使用浮点步长可能到不了预期的stop值。</p><p>这时候可以使用<code>np.linspace()</code>(尤其适用于绘图和数值计算,默认包含重点)</p></li></ul><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="comment"># 由于浮点精度影响，结果可能不如预期绝对精确</span></span><br><span class="line">a=np.arange(<span class="number">0</span>, <span class="number">0.4</span>, <span class="number">0.1</span>)</span><br><span class="line">b=np.linspace(<span class="number">0</span>, <span class="number">1</span>, <span class="number">5</span>) <span class="comment">#把1分成5段</span></span><br><span class="line"><span class="built_in">print</span>(a)</span><br><span class="line"><span class="built_in">print</span>(b)</span><br><span class="line"><span class="comment">#输出结果</span></span><br><span class="line">[<span class="number">0.</span>  <span class="number">0.1</span> <span class="number">0.2</span> <span class="number">0.3</span>]</span><br><span class="line">[<span class="number">0.</span>   <span class="number">0.25</span> <span class="number">0.5</span>  <span class="number">0.75</span> <span class="number">1.</span>  ]</span><br></pre></td></tr></table></div></figure><ul><li>当 <code>step</code>为负数时，<code>start</code>应大于 <code>stop</code>，否则将得到空数组</li></ul><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">a=np.arange(<span class="number">2</span>,<span class="number">7</span>,-<span class="number">1</span>)</span><br><span class="line">b=np.arange(<span class="number">7</span>,<span class="number">2</span>,-<span class="number">1</span>)</span><br><span class="line"><span class="built_in">print</span>(a)</span><br><span class="line"><span class="built_in">print</span>(b)</span><br><span class="line"><span class="comment">#输出结果</span></span><br><span class="line">[]</span><br><span class="line">[<span class="number">7</span> <span class="number">6</span> <span class="number">5</span> <span class="number">4</span> <span class="number">3</span>]</span><br></pre></td></tr></table></div></figure><ul><li>步长step不可为0，否则数组会无限长，抛出<code>ValueError</code>错误</li></ul>        <h2 id="ndarray对象属性"   >          <a href="#ndarray对象属性" class="heading-link"><i class="fas fa-link"></i></a><a href="#ndarray对象属性" class="headerlink" title="ndarray对象属性"></a>ndarray对象属性</h2>      <ul><li>        <h5 id="ndarray-ndim"   >          <a href="#ndarray-ndim" class="heading-link"><i class="fas fa-link"></i></a><a href="#ndarray-ndim" class="headerlink" title="ndarray.ndim"></a>ndarray.ndim</h5>      </li></ul><p>ndarray.ndim 用于获取<strong>数组的维度数量</strong>（即数组的轴数）。</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">a=np.arange(<span class="number">5</span>)</span><br><span class="line"><span class="built_in">print</span>(a.ndim) <span class="comment">#输出为1，这时候只有一个维度数量</span></span><br><span class="line">b=np.array([[<span class="number">1</span>,<span class="number">2</span>],[<span class="number">3</span>,<span class="number">4</span>]])</span><br><span class="line"><span class="built_in">print</span>(b.ndim)<span class="comment">#输出为2，有两个维度数量</span></span><br></pre></td></tr></table></div></figure><ul><li>        <h5 id="ndarray-shape"   >          <a href="#ndarray-shape" class="heading-link"><i class="fas fa-link"></i></a><a href="#ndarray-shape" class="headerlink" title="ndarray.shape"></a>ndarray.shape</h5>      </li></ul><p>ndarray.shape 表示数组的维度，<strong>返回一个元组</strong>，这个元组的<strong>长度就是维度的数目</strong>，即 ndim 属性(秩)。比如，一个二维数组，其维度表示”行数”和”列数”。</p><p>ndarray.shape 也可以用于<strong>调整数组大小</strong>。</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np  </span><br><span class="line"></span><br><span class="line">a = np.array([[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],[<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>]])  </span><br><span class="line"><span class="built_in">print</span> (a.shape)</span><br><span class="line"><span class="comment">#输出结果为（2，3）</span></span><br><span class="line">a = np.array([[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],[<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>]]) </span><br><span class="line">a.shape =  (<span class="number">3</span>,<span class="number">2</span>)  <span class="comment">#把原本二行三列的数组改成三行二列</span></span><br><span class="line"><span class="built_in">print</span> (a)</span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">输出结果为</span></span><br><span class="line"><span class="string">[[1 2]</span></span><br><span class="line"><span class="string"> [3 4]</span></span><br><span class="line"><span class="string"> [5 6]]</span></span><br><span class="line"><span class="string"> &#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="comment">#当然也可以使用reshape方法调整数组大小</span></span><br><span class="line">b = a.reshape(<span class="number">3</span>,<span class="number">2</span>) </span><br><span class="line"><span class="built_in">print</span>(b)</span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">输出结果为</span></span><br><span class="line"><span class="string">[[1 2]</span></span><br><span class="line"><span class="string"> [3 4]</span></span><br><span class="line"><span class="string"> [5 6]]</span></span><br><span class="line"><span class="string"> &#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></div></figure><ul><li>        <h5 id="ndarray-itemsize"   >          <a href="#ndarray-itemsize" class="heading-link"><i class="fas fa-link"></i></a><a href="#ndarray-itemsize" class="headerlink" title="ndarray.itemsize"></a>ndarray.itemsize</h5>      </li></ul><p><code>ndarray.itemsize</code> 以<strong>字节</strong>的形式<strong>返回数组中每一个元素的大小。</strong></p><p>例如，一个元素类型为 float64 的数组 itemsize 属性值为 8(float64 占用 64 个 bits，每个字节长度为 8，所以 64&#x2F;8，占用 8 个字节），又如，一个元素类型为 complex32 的数组 item 属性为 4（32&#x2F;8）。</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np </span><br><span class="line"> </span><br><span class="line"><span class="comment"># 数组的 dtype 为 int8（一个字节）  </span></span><br><span class="line">x = np.array([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>], dtype = np.int8)  </span><br><span class="line"><span class="built_in">print</span> (x.itemsize)</span><br><span class="line"> </span><br><span class="line"><span class="comment"># 数组的 dtype 现在为 float64（八个字节） </span></span><br><span class="line">y = np.array([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>], dtype = np.float64)  </span><br><span class="line"><span class="built_in">print</span> (y.itemsize)</span><br></pre></td></tr></table></div></figure>        <h2 id="创建数组的其他方式"   >          <a href="#创建数组的其他方式" class="heading-link"><i class="fas fa-link"></i></a><a href="#创建数组的其他方式" class="headerlink" title="创建数组的其他方式"></a>创建数组的其他方式</h2>      <ol><li>        <h5 id="numpy-empty"   >          <a href="#numpy-empty" class="heading-link"><i class="fas fa-link"></i></a><a href="#numpy-empty" class="headerlink" title="numpy.empty"></a>numpy.empty</h5>      </li></ol><p><code>numpy.empty</code> 方法用来创建一个指定形状（shape）、数据类型（dtype）且未初始化的数组：</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">numpy.empty(shape, dtype = <span class="built_in">float</span>, order = <span class="string">&#x27;C&#x27;</span>)</span><br></pre></td></tr></table></div></figure><p>参数说明：</p><div class="table-container"><table><thead><tr><th align="left">参数</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">shape</td><td align="left">数组形状</td></tr><tr><td align="left">dtype</td><td align="left">数据类型，可选</td></tr><tr><td align="left">order</td><td align="left">有”C”和”F”两个选项,分别代表，行优先和列优先，在计算机内存中的存储元素的顺序。</td></tr></tbody></table></div><p>下面是一个创建空数组的实例：</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">x = np.empty([<span class="number">3</span>,<span class="number">2</span>], dtype = <span class="built_in">int</span>)</span><br><span class="line"><span class="built_in">print</span> (x)</span><br></pre></td></tr></table></div></figure><p>输出结果为：</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">[[ 6917529027641081856  5764616291768666155]</span><br><span class="line"> [ 6917529027641081859 -5764598754299804209]</span><br><span class="line"> [          4497473538      844429428932120]]</span><br></pre></td></tr></table></div></figure><p><strong>注意</strong> − 数组元素为随机值，因为它们未初始化。</p><ul><li><p><strong>“垃圾值”的来源</strong>：<code>np.empty</code>为了追求极致的速度，在分配数组内存后，<strong>并不会用零或其他特定值去覆盖这块内存区域</strong></p><p>。这意味着你看到的是这块内存之前被使用后留下的“残影”或任意数据。因此，每次运行程序，或者在不同的计算机上运行，得到的结果很可能都不一样</p><p>。</p></li><li><p><strong>为何有时显示为零</strong>：你可能会在某些情况下看到输出结果全是零。这<strong>并不代表数组被初始化了</strong>。这通常是因为操作系统在分配新内存页时，出于安全考虑会将其清零；或者NumPy恰好复用了一块之前已经被清零的内存区域</p><p>。这是一个巧合，并非函数保证的行为。</p></li><li><p><strong>性能与安全的权衡</strong>：<code>np.empty</code>的设计初衷就是<strong>高性能</strong></p><p>。在你需要创建一个大型数组，并计划立刻用你自己的数据完全填充它时（例如，通过一个计算过程），使用 <code>np.empty</code>可以节省掉初始化为零的开销。但你必须牢记，在手动填充之前，数组内的值是无效且不可依赖的</p><p>。</p></li></ul>        <h5 id="2-numpy-zeros"   >          <a href="#2-numpy-zeros" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-numpy-zeros" class="headerlink" title="2.numpy.zeros"></a>2.numpy.zeros</h5>      <p>创建指定大小的数组，数组元素以 0 来填充：</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">numpy.zeros(shape, dtype = <span class="built_in">float</span>, order = <span class="string">&#x27;C&#x27;</span>)</span><br></pre></td></tr></table></div></figure><p>参数说明：</p><div class="table-container"><table><thead><tr><th align="left">参数</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">shape</td><td align="left">数组形状</td></tr><tr><td align="left">dtype</td><td align="left">数据类型，可选</td></tr><tr><td align="left">order</td><td align="left">‘C’ 用于 C 的行数组，或者 ‘F’ 用于 FORTRAN 的列数组</td></tr></tbody></table></div>        <h2 id="实例"   >          <a href="#实例" class="heading-link"><i class="fas fa-link"></i></a><a href="#实例" class="headerlink" title="实例"></a>实例</h2>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np  </span><br><span class="line"><span class="comment"># 默认为浮点数</span></span><br><span class="line">x = np.zeros(<span class="number">5</span>)</span><br><span class="line"><span class="built_in">print</span>(x)</span><br><span class="line"><span class="comment"># 设置类型为整数</span></span><br><span class="line">y = np.zeros((<span class="number">5</span>,), dtype = <span class="built_in">int</span>)</span><br><span class="line"><span class="built_in">print</span>(y)</span><br><span class="line"><span class="comment"># 自定义类型</span></span><br><span class="line">z = np.zeros((<span class="number">2</span>,<span class="number">2</span>), dtype = [(<span class="string">&#x27;x&#x27;</span>, <span class="string">&#x27;i4&#x27;</span>), (<span class="string">&#x27;y&#x27;</span>, <span class="string">&#x27;i4&#x27;</span>)])</span><br><span class="line"><span class="built_in">print</span>(z)</span><br></pre></td></tr></table></div></figure><p>输出结果为：</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">[<span class="number">0.</span> <span class="number">0.</span> <span class="number">0.</span> <span class="number">0.</span> <span class="number">0.</span>]</span><br><span class="line">[<span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span> <span class="number">0</span>]</span><br><span class="line">[[(<span class="number">0</span>, <span class="number">0</span>) (<span class="number">0</span>, <span class="number">0</span>)]</span><br><span class="line"> [(<span class="number">0</span>, <span class="number">0</span>) (<span class="number">0</span>, <span class="number">0</span>)]]</span><br></pre></td></tr></table></div></figure>        <h5 id="3-numpy-ones"   >          <a href="#3-numpy-ones" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-numpy-ones" class="headerlink" title="3.numpy.ones"></a>3.numpy.ones</h5>      <p>和上面一样，0换成1，不再赘述</p>        <h5 id="4-numpy-zeros-like"   >          <a href="#4-numpy-zeros-like" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-numpy-zeros-like" class="headerlink" title="4.numpy.zeros_like"></a>4.numpy.zeros_like</h5>      <p>numpy.zeros_like 用于创建一个与给定数组具有相同形状的数组，数组元素以 0 来填充。</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"> </span><br><span class="line"><span class="comment"># 创建一个 3x3 的二维数组</span></span><br><span class="line">arr = np.array([[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>], [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>], [<span class="number">7</span>, <span class="number">8</span>, <span class="number">9</span>]])</span><br><span class="line"> </span><br><span class="line"><span class="comment"># 创建一个与 arr 形状相同的，所有元素都为 0 的数组</span></span><br><span class="line">zeros_arr = np.zeros_like(arr)</span><br><span class="line"><span class="built_in">print</span>(zeros_arr)</span><br></pre></td></tr></table></div></figure><p>输出结果为</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">[[0 0 0]</span><br><span class="line"> [0 0 0]</span><br><span class="line"> [0 0 0]]</span><br></pre></td></tr></table></div></figure>        <h5 id="5-numpy-ones-like"   >          <a href="#5-numpy-ones-like" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-numpy-ones-like" class="headerlink" title="5.numpy.ones_like"></a>5.numpy.ones_like</h5>      <p>numpy.zeros_like 用于创建一个与给定数组具有相同形状的数组，数组元素以 1 来填充。</p>        <h2 id="4-切片和索引"   >          <a href="#4-切片和索引" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-切片和索引" class="headerlink" title="4.切片和索引"></a>4.切片和索引</h2>      <p>ndarray对象的内容可以通过<strong>索引或切片</strong>来<strong>访问和修改</strong>，与 Python 中 list 的切片操作一样。</p><p>ndarray 数组可以基于 0 - n 的下标进行索引，切片对象可以通过<strong>内置</strong>的 <strong>slice</strong> 函数，并设置 start, stop 及 step 参数进行，从原数组中切割出一个新数组。</p>        <h5 id="slice切割（了解即可，不推荐）"   >          <a href="#slice切割（了解即可，不推荐）" class="heading-link"><i class="fas fa-link"></i></a><a href="#slice切割（了解即可，不推荐）" class="headerlink" title="slice切割（了解即可，不推荐）"></a>slice切割（了解即可，不推荐）</h5>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">a=np.arange(<span class="number">10</span>)</span><br><span class="line">s=<span class="built_in">slice</span>(<span class="number">2</span>,<span class="number">7</span>,<span class="number">2</span>) <span class="comment">#从索引2到索引7停止，步长为2</span></span><br><span class="line"><span class="built_in">print</span>(a[s])</span><br><span class="line"></span><br><span class="line"><span class="comment">#输出结果</span></span><br><span class="line"><span class="comment">#[2 4 6]</span></span><br></pre></td></tr></table></div></figure>        <h5 id="冒号分隔切片-推荐，和前面学的list相通"   >          <a href="#冒号分隔切片-推荐，和前面学的list相通" class="heading-link"><i class="fas fa-link"></i></a><a href="#冒号分隔切片-推荐，和前面学的list相通" class="headerlink" title="冒号分隔切片(推荐，和前面学的list相通)"></a>冒号分隔切片(推荐，和前面学的list相通)</h5>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">a=np.arange(<span class="number">10</span>)</span><br><span class="line"><span class="built_in">print</span>(a[<span class="number">2</span>:<span class="number">7</span>:<span class="number">2</span>])<span class="comment">#输出结果[2 4 6]</span></span><br><span class="line"><span class="built_in">print</span>(a[<span class="number">5</span>])<span class="comment">#输出结果[5]</span></span><br><span class="line"><span class="built_in">print</span>(a[<span class="number">2</span>:])<span class="comment">#输出结果[2 3 4 5 6 7 8 9 10]</span></span><br><span class="line"><span class="built_in">print</span>(a[<span class="number">2</span>:<span class="number">5</span>])<span class="comment">#输出结果[2 3 4]</span></span><br><span class="line"></span><br></pre></td></tr></table></div></figure><p>上面我们演示的是单维数组，多维数组也是同理</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">a=np.arange(<span class="number">10</span>).reshape(<span class="number">2</span>,<span class="number">5</span>)</span><br><span class="line"><span class="built_in">print</span>(a[<span class="number">1</span>:])<span class="comment">#这里表示第一行之后的每一行</span></span><br><span class="line"><span class="comment">#输出结果</span></span><br><span class="line"><span class="comment">#[[5 6 7 8 9]]</span></span><br></pre></td></tr></table></div></figure>        <h5 id="省略号切片"   >          <a href="#省略号切片" class="heading-link"><i class="fas fa-link"></i></a><a href="#省略号切片" class="headerlink" title="省略号切片"></a>省略号切片</h5>      <p>切片还可以包括省略号 <strong>…</strong>，来使选择元组的长度与数组的维度相同。 如果在行位置使用省略号，它将返回包含行中元素的 ndarray。</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"> </span><br><span class="line">a = np.array([[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],[<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>],[<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>]])  </span><br><span class="line"><span class="built_in">print</span> (a[...,<span class="number">1</span>])   <span class="comment"># 第2列元素</span></span><br><span class="line"><span class="built_in">print</span> (a[<span class="number">1</span>,...])   <span class="comment"># 第2行元素</span></span><br><span class="line"><span class="built_in">print</span> (a[...,<span class="number">1</span>:])  <span class="comment"># 第2列及剩下的所有元素</span></span><br></pre></td></tr></table></div></figure><p>输出结果为</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">[2 4 5]</span><br><span class="line">[3 4 5]</span><br><span class="line">[[2 3]</span><br><span class="line"> [4 5]</span><br><span class="line"> [5 6]]</span><br></pre></td></tr></table></div></figure>        <h2 id="高级索引"   >          <a href="#高级索引" class="heading-link"><i class="fas fa-link"></i></a><a href="#高级索引" class="headerlink" title="高级索引"></a>高级索引</h2>      <p>NumPy 比一般的 Python 序列提供更多的索引方式。</p><p>除了之前看到的用整数和切片的索引外，数组可以由<strong>整数数组索引、布尔索引及花式索引。</strong></p>        <h5 id="整数数组索引"   >          <a href="#整数数组索引" class="heading-link"><i class="fas fa-link"></i></a><a href="#整数数组索引" class="headerlink" title="整数数组索引"></a>整数数组索引</h5>      <p>整数数组索引是指使用一个数组来访问另一个数组的元素。这个数组中的每个元素都是目标数组中某个维度上的索引值。以下实例获取数组中 <strong>(0,0)，(1,1)</strong> 和 <strong>(2,0)</strong> 位置处的元素。</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np </span><br><span class="line"> </span><br><span class="line">x = np.array([[<span class="number">1</span>,  <span class="number">2</span>],  [<span class="number">3</span>,  <span class="number">4</span>],  [<span class="number">5</span>,  <span class="number">6</span>]]) </span><br><span class="line">y = x[[<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>],  [<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>]]  </span><br><span class="line"><span class="built_in">print</span> (y)</span><br></pre></td></tr></table></div></figure><p>输出结果为</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[1 4 5]</span><br></pre></td></tr></table></div></figure><p>整数数组索引还可以和<strong>切片：或……结合</strong></p><p>已知我们如果想获得坐标（1，2）的元素可以这么写</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">a=np.array([[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],[<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>],[<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>]])</span><br><span class="line"><span class="built_in">print</span>(a[<span class="number">1</span>,<span class="number">2</span>])</span><br></pre></td></tr></table></div></figure><p>同样我们可以把逗号分隔的两个参数用切片改一下</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">a=np.array([[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],[<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>],[<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>]])</span><br><span class="line">b=a[<span class="number">1</span>:<span class="number">3</span>,<span class="number">1</span>:<span class="number">3</span>]<span class="comment">#a[1:3,[1,2]]效果一样</span></span><br><span class="line"><span class="built_in">print</span>(b)</span><br></pre></td></tr></table></div></figure><p>这样输出的就是一到二行的一到二列</p>        <h5 id="布尔索引"   >          <a href="#布尔索引" class="heading-link"><i class="fas fa-link"></i></a><a href="#布尔索引" class="headerlink" title="布尔索引"></a>布尔索引</h5>      <p>还可以通过布尔索引来进行筛选，布尔索引通过布尔运算（如：比较运算符）来获取符合指定条件的元素的数组。</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np </span><br><span class="line"> </span><br><span class="line">x = np.array([[  <span class="number">0</span>,  <span class="number">1</span>,  <span class="number">2</span>],[  <span class="number">3</span>,  <span class="number">4</span>,  <span class="number">5</span>],[  <span class="number">6</span>,  <span class="number">7</span>,  <span class="number">8</span>],[  <span class="number">9</span>,  <span class="number">10</span>,  <span class="number">11</span>]])  </span><br><span class="line"><span class="built_in">print</span> (<span class="string">&#x27;我们的数组是：&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span> (x)</span><br><span class="line"><span class="built_in">print</span> (<span class="string">&#x27;\n&#x27;</span>)</span><br><span class="line"><span class="comment"># 现在我们会打印出大于 5 的元素  </span></span><br><span class="line"><span class="built_in">print</span>  (<span class="string">&#x27;大于 5 的元素是：&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span> (x[x &gt;  <span class="number">5</span>])</span><br></pre></td></tr></table></div></figure><p>输出结果为：</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">我们的数组是：</span><br><span class="line">[[ 0  1  2]</span><br><span class="line"> [ 3  4  5]</span><br><span class="line"> [ 6  7  8]</span><br><span class="line"> [ 9 10 11]]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">大于 5 的元素是：</span><br><span class="line">[ 6  7  8  9 10 11]</span><br></pre></td></tr></table></div></figure><p>还可以使用<code>~</code>（取补运算符）来过滤</p><p>以下实例使用了 <strong>~</strong>（取补运算符）来过滤 NaN。</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">a = np.array([np.nan,  <span class="number">1</span>,<span class="number">2</span>,np.nan,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>])</span><br><span class="line"><span class="built_in">print</span> (a[~np.isnan(a)])</span><br></pre></td></tr></table></div></figure><p>输出结果为：</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[ 1.   2.   3.   4.   5.]</span><br></pre></td></tr></table></div></figure><p>以下实例演示如何从数组中过滤掉非复数元素。</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">a = np.array([<span class="number">1</span>,  <span class="number">2</span>+<span class="number">6j</span>,  <span class="number">5</span>,  <span class="number">3.5</span>+<span class="number">5j</span>])</span><br><span class="line"><span class="built_in">print</span> (a[np.iscomplex(a)])</span><br></pre></td></tr></table></div></figure><p>输出如下：</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[2.0+6.j  3.5+5.j]</span><br></pre></td></tr></table></div></figure>        <h5 id="花式索引"   >          <a href="#花式索引" class="heading-link"><i class="fas fa-link"></i></a><a href="#花式索引" class="headerlink" title="花式索引"></a>花式索引</h5>      <p>花式索引根据索引数组的值作为目标数组的某个轴的下标进行索引</p><p>对于使用一维整型数组作为索引，如果目标是一维数组，那么索引的结果就是对应位置的元素，如果目标是二维数组，那么就是对应<strong>下标的行</strong>。</p><p>花式索引跟切片不一样，<strong>它总是将数据复制到新数组中</strong>。</p><p>对于一维数组</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line">x=np.arange(<span class="number">9</span>)</span><br><span class="line"><span class="built_in">print</span>(x)</span><br><span class="line">x1=x[[<span class="number">0</span>,<span class="number">6</span>]]<span class="comment">#花式索引</span></span><br><span class="line"><span class="built_in">print</span>(x2)</span><br></pre></td></tr></table></div></figure>        <h2 id="NumPy-广播-Broadcast"   >          <a href="#NumPy-广播-Broadcast" class="heading-link"><i class="fas fa-link"></i></a><a href="#NumPy-广播-Broadcast" class="headerlink" title="NumPy 广播(Broadcast)"></a>NumPy 广播(Broadcast)</h2>      <p>广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式， 对数组的算术运算通常在相应的元素上进行。</p><p>如果两个数组 a 和 b 形状相同，即满足 <strong>a.shape &#x3D;&#x3D; b.shape</strong>，那么 a*b 的结果就是 a 与 b 数组对应位相乘。这要求维数相同，且各维度的长度相同。</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np </span><br><span class="line"> </span><br><span class="line">a = np.array([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>]) </span><br><span class="line">b = np.array([<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>,<span class="number">40</span>]) </span><br><span class="line">c = a * b </span><br><span class="line"><span class="built_in">print</span> (c)</span><br><span class="line"><span class="comment">#[ 10  40  90 160]</span></span><br></pre></td></tr></table></div></figure><p>当运算中的 2 个数组的形状不同时，numpy 将自动触发广播机制。如：</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np </span><br><span class="line"> </span><br><span class="line">a = np.array([[ <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>],</span><br><span class="line">           [<span class="number">10</span>,<span class="number">10</span>,<span class="number">10</span>],</span><br><span class="line">           [<span class="number">20</span>,<span class="number">20</span>,<span class="number">20</span>],</span><br><span class="line">           [<span class="number">30</span>,<span class="number">30</span>,<span class="number">30</span>]])</span><br><span class="line">b = np.array([<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>])</span><br><span class="line"><span class="built_in">print</span>(a + b)</span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;[[ 0  1  2]</span></span><br><span class="line"><span class="string"> [10 11 12]</span></span><br><span class="line"><span class="string"> [20 21 22]</span></span><br><span class="line"><span class="string"> [30 31 32]]</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></div></figure>        <h2 id="NumPy迭代数组"   >          <a href="#NumPy迭代数组" class="heading-link"><i class="fas fa-link"></i></a><a href="#NumPy迭代数组" class="headerlink" title="NumPy迭代数组"></a>NumPy迭代数组</h2>              <h4 id="1-nditer的迭代顺序"   >          <a href="#1-nditer的迭代顺序" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-nditer的迭代顺序" class="headerlink" title="1.nditer的迭代顺序"></a>1.nditer的迭代顺序</h4>      <p>NumPy 迭代器对象 numpy.nditer 提供了一种<strong>灵活访问一个</strong>或者<strong>多个数组元素</strong>的方式。</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"> </span><br><span class="line">a = np.arange(<span class="number">6</span>).reshape(<span class="number">2</span>,<span class="number">3</span>)</span><br><span class="line"><span class="built_in">print</span> (<span class="string">&#x27;原始数组是：&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span> (a)</span><br><span class="line"><span class="built_in">print</span> (<span class="string">&#x27;\n&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span> (<span class="string">&#x27;迭代输出元素：&#x27;</span>)</span><br><span class="line"><span class="keyword">for</span> x <span class="keyword">in</span> np.nditer(a):</span><br><span class="line">    <span class="built_in">print</span> (x, end=<span class="string">&quot;, &quot;</span> )</span><br><span class="line"><span class="built_in">print</span> (<span class="string">&#x27;\n&#x27;</span>)</span><br></pre></td></tr></table></div></figure><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">原始数组是：</span><br><span class="line">[[0 1 2]</span><br><span class="line"> [3 4 5]]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">迭代输出元素：</span><br><span class="line">0, 1, 2, 3, 4, 5,</span><br></pre></td></tr></table></div></figure><p>以上实例不是使用标准 C 或者 Fortran 顺序，默认是行序优先</p><p>这反映了默认情况下只需访问每个元素，而无需考虑其特定顺序。我们可以通过迭代上述数组的转置来看到这一点，并与以 C 顺序访问数组转置的 copy 方式做对比，如下实例：</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"> </span><br><span class="line">a = np.arange(<span class="number">6</span>).reshape(<span class="number">2</span>,<span class="number">3</span>)</span><br><span class="line"><span class="keyword">for</span> x <span class="keyword">in</span> np.nditer(a.T):</span><br><span class="line">    <span class="built_in">print</span> (x, end=<span class="string">&quot;, &quot;</span> )</span><br><span class="line"><span class="built_in">print</span> (<span class="string">&#x27;\n&#x27;</span>)</span><br><span class="line"> </span><br><span class="line"><span class="keyword">for</span> x <span class="keyword">in</span> np.nditer(a.T.copy(order=<span class="string">&#x27;C&#x27;</span>)):</span><br><span class="line">    <span class="built_in">print</span> (x, end=<span class="string">&quot;, &quot;</span> )</span><br><span class="line"><span class="built_in">print</span> (<span class="string">&#x27;\n&#x27;</span>)</span><br></pre></td></tr></table></div></figure><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">0, 1, 2, 3, 4, 5, </span><br><span class="line"></span><br><span class="line">0, 3, 1, 4, 2, 5, </span><br></pre></td></tr></table></div></figure>        <h5 id="第一个循环：np-nditer-a-T"   >          <a href="#第一个循环：np-nditer-a-T" class="heading-link"><i class="fas fa-link"></i></a><a href="#第一个循环：np-nditer-a-T" class="headerlink" title="第一个循环：np.nditer(a.T)"></a>第一个循环：<code>np.nditer(a.T)</code></h5>      <p>默认情况下，<code>nditer</code>会按照数组在内存中的存储顺序进行迭代。NumPy数组默认以行优先(‘C’风格)顺序存储。</p><p><strong>关键点</strong>：<code>a.T</code>是转置视图(view)，不是副本(copy)，它保持了原始数组的内存布局。虽然逻辑上是3x2，但物理存储仍然是原始2x3数组的顺序。</p><p>因此，迭代<code>a.T</code>时实际是按照原始数组的内存顺序访问元素</p>        <h5 id="第二个循环：np-nditer-a-T-copy-order-C"   >          <a href="#第二个循环：np-nditer-a-T-copy-order-C" class="heading-link"><i class="fas fa-link"></i></a><a href="#第二个循环：np-nditer-a-T-copy-order-C" class="headerlink" title="第二个循环：np.nditer(a.T.copy(order=&#39;C&#39;))"></a>第二个循环：<code>np.nditer(a.T.copy(order=&#39;C&#39;))</code></h5>      <p>这里显式创建了一个C顺序的副本。<code>order=&#39;C&#39;</code>指定了行优先存储。</p><p>副本会按照转置后的逻辑形状(3x2)和指定的C顺序重新排列内存中的元素，所以迭代顺序就是转置后的行优先顺序：</p>        <h4 id="2-nditer的flags参数"   >          <a href="#2-nditer的flags参数" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-nditer的flags参数" class="headerlink" title="2.nditer的flags参数"></a>2.nditer的flags参数</h4>      <p>nditer 类的构造器拥有 flags 参数，它可以接受下列值：</p><div class="table-container"><table><thead><tr><th align="left">参数</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left"><code>c_index</code></td><td align="left">可以跟踪 C 顺序的索引</td></tr><tr><td align="left"><code>f_index</code></td><td align="left">可以跟踪 Fortran 顺序的索引</td></tr><tr><td align="left"><code>multi_index</code></td><td align="left">每次迭代可以跟踪一种索引类型</td></tr><tr><td align="left"><code>external_loop</code></td><td align="left">给出的值是具有多个值的一维数组，而不是零维数组</td></tr></tbody></table></div><p>在下面的实例中，迭代器遍历对应于每列，并组合为一维数组。</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np </span><br><span class="line">a = np.arange(<span class="number">0</span>,<span class="number">60</span>,<span class="number">5</span>) </span><br><span class="line">a = a.reshape(<span class="number">3</span>,<span class="number">4</span>)  </span><br><span class="line"><span class="built_in">print</span> (<span class="string">&#x27;原始数组是：&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span> (a)</span><br><span class="line"><span class="built_in">print</span> (<span class="string">&#x27;\n&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span> (<span class="string">&#x27;修改后的数组是：&#x27;</span>)</span><br><span class="line"><span class="keyword">for</span> x <span class="keyword">in</span> np.nditer(a, flags =  [<span class="string">&#x27;external_loop&#x27;</span>], order =  <span class="string">&#x27;F&#x27;</span>):  </span><br><span class="line">   <span class="built_in">print</span> (x, end=<span class="string">&quot;, &quot;</span> )</span><br></pre></td></tr></table></div></figure><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">原始数组是：</span><br><span class="line">[[ 0  5 10 15]</span><br><span class="line"> [20 25 30 35]</span><br><span class="line"> [40 45 50 55]]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">修改后的数组是：</span><br><span class="line">[ 0 20 40], [ 5 25 45], [10 30 50], [15 35 55],</span><br></pre></td></tr></table></div></figure>        <h4 id="3-nditer修改数组中元素的值"   >          <a href="#3-nditer修改数组中元素的值" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-nditer修改数组中元素的值" class="headerlink" title="3.nditer修改数组中元素的值"></a>3.nditer修改数组中元素的值</h4>      <p>nditer 对象有另一个可选参数 <strong>op_flags</strong>。 默认情况下，nditer 将视待迭代遍历的数组为<strong>只读对象（read-only）</strong>，为了在遍历数组的同时，实现对数组元素值的修改，<strong>必须指定 readwrite 或者 writeonly 的模式。</strong></p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line">a=np.arange(<span class="number">0</span>,<span class="number">60</span>,<span class="number">5</span>)</span><br><span class="line">a=a.reshape(<span class="number">3</span>,<span class="number">4</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;原始数组是：&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(a)</span><br><span class="line"><span class="keyword">for</span> x <span class="keyword">in</span> np.nditer(a,op_flags=[<span class="string">&#x27;readwrite&#x27;</span>]):</span><br><span class="line">x[...]=<span class="number">2</span>*x</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;修改后的数组是：&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(a)</span><br></pre></td></tr></table></div></figure><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">原始数组是：</span><br><span class="line">[[ 0  5 10 15]</span><br><span class="line"> [20 25 30 35]</span><br><span class="line"> [40 45 50 55]]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">修改后的数组是：</span><br><span class="line">[[  0  10  20  30]</span><br><span class="line"> [ 40  50  60  70]</span><br><span class="line"> [ 80  90 100 110]]</span><br></pre></td></tr></table></div></figure>        <h4 id="4-广播迭代"   >          <a href="#4-广播迭代" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-广播迭代" class="headerlink" title="4.广播迭代"></a>4.广播迭代</h4>      <p>如果两个数组是可广播的，nditer 组合对象能够同时迭代它们。 假设数组 a 的维度为 3X4，数组 b 的维度为 1X4 ，则使用以下迭代器</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np </span><br><span class="line"> </span><br><span class="line">a = np.arange(<span class="number">0</span>,<span class="number">60</span>,<span class="number">5</span>) </span><br><span class="line">a = a.reshape(<span class="number">3</span>,<span class="number">4</span>)  </span><br><span class="line"><span class="built_in">print</span>  (<span class="string">&#x27;第一个数组为：&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span> (a)</span><br><span class="line"><span class="built_in">print</span>  (<span class="string">&#x27;\n&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span> (<span class="string">&#x27;第二个数组为：&#x27;</span>)</span><br><span class="line">b = np.array([<span class="number">1</span>,  <span class="number">2</span>,  <span class="number">3</span>,  <span class="number">4</span>], dtype =  <span class="built_in">int</span>)  </span><br><span class="line"><span class="built_in">print</span> (b)</span><br><span class="line"><span class="built_in">print</span> (<span class="string">&#x27;\n&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span> (<span class="string">&#x27;修改后的数组为：&#x27;</span>)</span><br><span class="line"><span class="keyword">for</span> x,y <span class="keyword">in</span> np.nditer([a,b]):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;%d:%d&quot;</span> % (x,y),end=<span class="string">&quot;,&quot;</span>)</span><br></pre></td></tr></table></div></figure><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">第一个数组为：</span><br><span class="line">[[ 0  5 10 15]</span><br><span class="line"> [20 25 30 35]</span><br><span class="line"> [40 45 50 55]]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">第二个数组为：</span><br><span class="line">[1 2 3 4]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">修改后的数组为：</span><br><span class="line">0:1, 5:2, 10:3, 15:4, 20:1, 25:2, 30:3, 35:4, 40:1, 45:2, 50:3, 55:4,</span><br></pre></td></tr></table></div></figure>        <h2 id="NumPy-数组操作常用知识点"   >          <a href="#NumPy-数组操作常用知识点" class="heading-link"><i class="fas fa-link"></i></a><a href="#NumPy-数组操作常用知识点" class="headerlink" title="NumPy 数组操作常用知识点"></a>NumPy 数组操作常用知识点</h2>              <h3 id="1-修改数组形状"   >          <a href="#1-修改数组形状" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-修改数组形状" class="headerlink" title="1. 修改数组形状"></a>1. 修改数组形状</h3>              <h4 id="1-1-reshape"   >          <a href="#1-1-reshape" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-1-reshape" class="headerlink" title="1.1 reshape"></a>1.1 reshape</h4>      <p>在不改变数据的情况下修改数组形状</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">a = np.arange(<span class="number">8</span>)</span><br><span class="line">b = a.reshape(<span class="number">4</span>,<span class="number">2</span>)  <span class="comment"># 将一维数组变为4行2列</span></span><br></pre></td></tr></table></div></figure>        <h4 id="1-2-flatten-和-ravel"   >          <a href="#1-2-flatten-和-ravel" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-2-flatten-和-ravel" class="headerlink" title="1.2 flatten 和 ravel"></a>1.2 flatten 和 ravel</h4>      <ul><li><strong>flatten</strong>：返回数组的拷贝，修改不影响原始数组</li><li><strong>ravel</strong>：返回数组视图，修改会影响原始数组</li></ul><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">a = np.arange(<span class="number">8</span>).reshape(<span class="number">2</span>,<span class="number">4</span>)</span><br><span class="line"><span class="built_in">print</span>(a.flatten())     <span class="comment"># 按行展开：[0 1 2 3 4 5 6 7]</span></span><br><span class="line"><span class="built_in">print</span>(a.ravel())       <span class="comment"># 按行展开：[0 1 2 3 4 5 6 7]</span></span><br><span class="line"><span class="built_in">print</span>(a.flatten(order=<span class="string">&#x27;F&#x27;</span>))  <span class="comment"># 按列展开：[0 4 1 5 2 6 3 7]</span></span><br></pre></td></tr></table></div></figure>        <h3 id="2-翻转数组"   >          <a href="#2-翻转数组" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-翻转数组" class="headerlink" title="2. 翻转数组"></a>2. 翻转数组</h3>              <h4 id="2-1-transpose-和-T"   >          <a href="#2-1-transpose-和-T" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-1-transpose-和-T" class="headerlink" title="2.1 transpose 和 T"></a>2.1 transpose 和 T</h4>      <p>转置数组（行列互换）</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">a = np.arange(<span class="number">12</span>).reshape(<span class="number">3</span>,<span class="number">4</span>)</span><br><span class="line"><span class="built_in">print</span>(np.transpose(a))  <span class="comment"># 转置</span></span><br><span class="line"><span class="built_in">print</span>(a.T)             <span class="comment"># 等价写法</span></span><br></pre></td></tr></table></div></figure>        <h3 id="3-修改数组维度"   >          <a href="#3-修改数组维度" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-修改数组维度" class="headerlink" title="3. 修改数组维度"></a>3. 修改数组维度</h3>              <h4 id="3-1-expand-dims"   >          <a href="#3-1-expand-dims" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-1-expand-dims" class="headerlink" title="3.1 expand_dims"></a>3.1 expand_dims</h4>      <p>扩展数组形状，在指定位置插入新轴</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">x = np.array([[<span class="number">1</span>,<span class="number">2</span>],[<span class="number">3</span>,<span class="number">4</span>]])</span><br><span class="line">y = np.expand_dims(x, axis=<span class="number">0</span>)  <span class="comment"># 在位置0插入轴，形状变为(1,2,2)</span></span><br></pre></td></tr></table></div></figure>        <h4 id="3-2-squeeze"   >          <a href="#3-2-squeeze" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-2-squeeze" class="headerlink" title="3.2 squeeze"></a>3.2 squeeze</h4>      <p>从数组形状中删除一维条目</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">x = np.arange(<span class="number">9</span>).reshape(<span class="number">1</span>,<span class="number">3</span>,<span class="number">3</span>)</span><br><span class="line">y = np.squeeze(x)  <span class="comment"># 形状从(1,3,3)变为(3,3)</span></span><br></pre></td></tr></table></div></figure>        <h3 id="4-连接数组"   >          <a href="#4-连接数组" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-连接数组" class="headerlink" title="4. 连接数组"></a>4. 连接数组</h3>              <h4 id="4-1-concatenate"   >          <a href="#4-1-concatenate" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-1-concatenate" class="headerlink" title="4.1 concatenate"></a>4.1 concatenate</h4>      <p><strong>沿指定轴连接数组</strong></p><p>注意：垂直堆叠要求垂直方向两个数组有对应的数字，若如下图则报错</p><p><img src="/../images/image-20251012141510642.png" alt="image-20251012141510642"></p><p><img src="/../images/image-20251012141615418.png" alt="image-20251012141615418"></p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">a = np.array([[<span class="number">1</span>,<span class="number">2</span>],[<span class="number">3</span>,<span class="number">4</span>]])</span><br><span class="line">b = np.array([[<span class="number">5</span>,<span class="number">6</span>],[<span class="number">7</span>,<span class="number">8</span>]])</span><br><span class="line"></span><br><span class="line"><span class="comment"># 沿轴0连接（垂直堆叠）</span></span><br><span class="line"><span class="built_in">print</span>(np.concatenate((a,b)))        <span class="comment"># [[1 2] [3 4] [5 6] [7 8]]</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 沿轴1连接（水平堆叠）</span></span><br><span class="line"><span class="built_in">print</span>(np.concatenate((a,b),axis=<span class="number">1</span>)) <span class="comment"># [[1 2 5 6] [3 4 7 8]]</span></span><br></pre></td></tr></table></div></figure>        <h4 id="4-2-stack"   >          <a href="#4-2-stack" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-2-stack" class="headerlink" title="4.2 stack"></a>4.2 stack</h4>      <p>沿新轴连接数组序列</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">print</span>(np.stack((a,b),<span class="number">0</span>))  <span class="comment"># 沿新轴0堆叠</span></span><br><span class="line"><span class="built_in">print</span>(np.stack((a,b),<span class="number">1</span>))  <span class="comment"># 沿新轴1堆叠</span></span><br></pre></td></tr></table></div></figure>        <h4 id="4-3-hstack-和-vstack"   >          <a href="#4-3-hstack-和-vstack" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-3-hstack-和-vstack" class="headerlink" title="4.3 hstack 和 vstack"></a>4.3 hstack 和 vstack</h4>      <ul><li><strong>hstack</strong>：水平堆叠（按列）</li><li><strong>vstack</strong>：垂直堆叠（按行）</li></ul><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">print</span>(np.hstack((a,b)))  <span class="comment"># 水平堆叠</span></span><br><span class="line"><span class="built_in">print</span>(np.vstack((a,b)))  <span class="comment"># 垂直堆叠</span></span><br></pre></td></tr></table></div></figure>        <h3 id="5-分割数组"   >          <a href="#5-分割数组" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-分割数组" class="headerlink" title="5. 分割数组"></a>5. 分割数组</h3>              <h4 id="5-1-split"   >          <a href="#5-1-split" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-1-split" class="headerlink" title="5.1 split"></a>5.1 split</h4>      <p>将数组分割为多个子数组</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">a = np.arange(<span class="number">9</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 平均分成3份</span></span><br><span class="line"><span class="built_in">print</span>(np.split(a,<span class="number">3</span>))  <span class="comment"># [array([0,1,2]), array([3,4,5]), array([6,7,8])]</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 在指定位置分割</span></span><br><span class="line"><span class="built_in">print</span>(np.split(a,[<span class="number">4</span>,<span class="number">7</span>]))  <span class="comment"># [array([0,1,2,3]), array([4,5,6]), array([7,8])]</span></span><br></pre></td></tr></table></div></figure>        <h4 id="5-2-hsplit-和-vsplit"   >          <a href="#5-2-hsplit-和-vsplit" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-2-hsplit-和-vsplit" class="headerlink" title="5.2 hsplit 和 vsplit"></a>5.2 hsplit 和 vsplit</h4>      <ul><li><strong>hsplit</strong>：水平分割（按列）</li><li><strong>vsplit</strong>：垂直分割（按行）</li></ul><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">a = np.arange(<span class="number">16</span>).reshape(<span class="number">4</span>,<span class="number">4</span>)</span><br><span class="line"><span class="built_in">print</span>(np.hsplit(a,<span class="number">2</span>))  <span class="comment"># 水平分成2份</span></span><br><span class="line"><span class="built_in">print</span>(np.vsplit(a,<span class="number">2</span>))  <span class="comment"># 垂直分成2份</span></span><br></pre></td></tr></table></div></figure>        <h3 id="6-数组元素的添加与删除"   >          <a href="#6-数组元素的添加与删除" class="heading-link"><i class="fas fa-link"></i></a><a href="#6-数组元素的添加与删除" class="headerlink" title="6. 数组元素的添加与删除"></a>6. 数组元素的添加与删除</h3>              <h4 id="6-1-append"   >          <a href="#6-1-append" class="heading-link"><i class="fas fa-link"></i></a><a href="#6-1-append" class="headerlink" title="6.1 append"></a>6.1 append</h4>      <p>在数组末尾添加值</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">a = np.array([[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],[<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>]])</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(np.append(a, [<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>]))              <span class="comment"># 展开后添加：[1 2 3 4 5 6 7 8 9]</span></span><br><span class="line"><span class="built_in">print</span>(np.append(a, [[<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>]], axis=<span class="number">0</span>))    <span class="comment"># 沿轴0添加</span></span><br><span class="line"><span class="built_in">print</span>(np.append(a, [[<span class="number">5</span>,<span class="number">5</span>,<span class="number">5</span>],[<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>]], axis=<span class="number">1</span>))  <span class="comment"># 沿轴1添加</span></span><br></pre></td></tr></table></div></figure>        <h4 id="6-2-insert"   >          <a href="#6-2-insert" class="heading-link"><i class="fas fa-link"></i></a><a href="#6-2-insert" class="headerlink" title="6.2 insert"></a>6.2 insert</h4>      <p>在指定位置插入值</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">a = np.array([[<span class="number">1</span>,<span class="number">2</span>],[<span class="number">3</span>,<span class="number">4</span>],[<span class="number">5</span>,<span class="number">6</span>]])</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(np.insert(a, <span class="number">3</span>, [<span class="number">11</span>,<span class="number">12</span>]))           <span class="comment"># 展开后插入</span></span><br><span class="line"><span class="built_in">print</span>(np.insert(a, <span class="number">1</span>, <span class="number">11</span>, axis=<span class="number">1</span>))        <span class="comment"># 沿轴1插入</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">[ 1  2  3 11 12  4  5  6]</span></span><br><span class="line"><span class="string">[[ 1 11  2]</span></span><br><span class="line"><span class="string"> [ 3 11  4]</span></span><br><span class="line"><span class="string"> [ 5 11  6]]</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br></pre></td></tr></table></div></figure>        <h4 id="6-3-delete"   >          <a href="#6-3-delete" class="heading-link"><i class="fas fa-link"></i></a><a href="#6-3-delete" class="headerlink" title="6.3 delete"></a>6.3 delete</h4>      <p>删除指定子数组</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">a = np.arange(<span class="number">12</span>).reshape(<span class="number">3</span>,<span class="number">4</span>)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(np.delete(a, <span class="number">5</span>))                    <span class="comment"># 展开后删除第5个元素</span></span><br><span class="line"><span class="built_in">print</span>(np.delete(a, <span class="number">1</span>, axis=<span class="number">1</span>))            <span class="comment"># 删除第1列</span></span><br></pre></td></tr></table></div></figure>        <h4 id="6-4-unique"   >          <a href="#6-4-unique" class="heading-link"><i class="fas fa-link"></i></a><a href="#6-4-unique" class="headerlink" title="6.4 unique"></a>6.4 unique</h4>      <p>去除数组中的重复元素</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">a = np.array([<span class="number">5</span>,<span class="number">2</span>,<span class="number">6</span>,<span class="number">2</span>,<span class="number">7</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">8</span>,<span class="number">2</span>,<span class="number">9</span>])</span><br><span class="line">u = np.unique(a)  <span class="comment"># [2 5 6 7 8 9]</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 返回元素出现次数</span></span><br><span class="line">u, indices = np.unique(a, return_counts=<span class="literal">True</span>)</span><br></pre></td></tr></table></div></figure>        <h2 id="NumPy-排序与条件筛选常用函数"   >          <a href="#NumPy-排序与条件筛选常用函数" class="heading-link"><i class="fas fa-link"></i></a><a href="#NumPy-排序与条件筛选常用函数" class="headerlink" title="NumPy 排序与条件筛选常用函数"></a>NumPy 排序与条件筛选常用函数</h2>              <h3 id="1-排序函数"   >          <a href="#1-排序函数" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-排序函数" class="headerlink" title="1. 排序函数"></a>1. 排序函数</h3>              <h4 id="1-1-numpy-sort"   >          <a href="#1-1-numpy-sort" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-1-numpy-sort" class="headerlink" title="1.1 numpy.sort()"></a>1.1 numpy.sort()</h4>      <p>返回输入数组的排序副本</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line"><span class="comment"># 基本排序</span></span><br><span class="line">arr = np.array([[<span class="number">3</span>, <span class="number">7</span>], [<span class="number">9</span>, <span class="number">1</span>]])</span><br><span class="line"><span class="built_in">print</span>(np.sort(arr))           <span class="comment"># 默认按行排序</span></span><br><span class="line"><span class="built_in">print</span>(np.sort(arr, axis=<span class="number">0</span>))   <span class="comment"># 按列排序</span></span><br></pre></td></tr></table></div></figure>        <h4 id="1-2-numpy-argsort"   >          <a href="#1-2-numpy-argsort" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-2-numpy-argsort" class="headerlink" title="1.2 numpy.argsort()"></a>1.2 numpy.argsort()</h4>      <p>返回数组值从小到大的索引值</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">x = np.array([<span class="number">3</span>, <span class="number">1</span>, <span class="number">2</span>])</span><br><span class="line">indices = np.argsort(x)      <span class="comment"># 返回 [1, 2, 0]</span></span><br><span class="line">sorted_x = x[indices]        <span class="comment"># 通过索引获取排序结果 [1, 2, 3]</span></span><br></pre></td></tr></table></div></figure>        <h3 id="2-最值索引函数"   >          <a href="#2-最值索引函数" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-最值索引函数" class="headerlink" title="2. 最值索引函数"></a>2. 最值索引函数</h3>              <h4 id="2-1-numpy-argmax-和-numpy-argmin"   >          <a href="#2-1-numpy-argmax-和-numpy-argmin" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-1-numpy-argmax-和-numpy-argmin" class="headerlink" title="2.1 numpy.argmax() 和 numpy.argmin()"></a>2.1 numpy.argmax() 和 numpy.argmin()</h4>      <p>返回最大&#x2F;最小元素的索引</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">arr = np.array([[<span class="number">30</span>, <span class="number">40</span>, <span class="number">70</span>], </span><br><span class="line">                [<span class="number">80</span>, <span class="number">20</span>, <span class="number">10</span>], </span><br><span class="line">                [<span class="number">50</span>, <span class="number">90</span>, <span class="number">60</span>]])</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(np.argmax(arr))        <span class="comment"># 全局最大值的索引：7</span></span><br><span class="line"><span class="built_in">print</span>(np.argmax(arr, axis=<span class="number">0</span>)) <span class="comment"># 每列最大值的索引：[1, 2, 0]</span></span><br><span class="line"><span class="built_in">print</span>(np.argmin(arr, axis=<span class="number">1</span>)) <span class="comment"># 每行最小值的索引：[0, 2, 0]</span></span><br></pre></td></tr></table></div></figure>        <h3 id="3-条件筛选函数"   >          <a href="#3-条件筛选函数" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-条件筛选函数" class="headerlink" title="3. 条件筛选函数"></a>3. 条件筛选函数</h3>              <h4 id="3-1-numpy-where"   >          <a href="#3-1-numpy-where" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-1-numpy-where" class="headerlink" title="3.1 numpy.where()"></a>3.1 numpy.where()</h4>      <p>返回满足条件的元素索引</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"># 创建示例数组</span><br><span class="line">arr = np.array([[1, 2, 3], </span><br><span class="line">                [4, 5, 6], </span><br><span class="line">                [7, 8, 9]])</span><br><span class="line"></span><br><span class="line"># 找出大于5的元素</span><br><span class="line">indices = np.where(arr &gt; 5)</span><br><span class="line">print(indices)  # 输出满足条件的行列索引</span><br><span class="line">print(arr[indices])  # 输出满足条件的元素 [6, 7, 8, 9]</span><br><span class="line"></span><br><span class="line"># 条件替换：将大于5的元素替换为0</span><br><span class="line">result = np.where(arr &gt; 5, 0, arr)</span><br><span class="line">print(result)</span><br></pre></td></tr></table></div></figure>        <h4 id="3-2-numpy-nonzero"   >          <a href="#3-2-numpy-nonzero" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-2-numpy-nonzero" class="headerlink" title="3.2 numpy.nonzero()"></a>3.2 numpy.nonzero()</h4>      <p>返回非零元素的索引</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">arr = np.array([[0, 1, 0], </span><br><span class="line">                [2, 0, 3], </span><br><span class="line">                [0, 4, 0]])</span><br><span class="line"></span><br><span class="line">nonzero_indices = np.nonzero(arr)</span><br><span class="line">print(nonzero_indices)  # 非零元素的位置</span><br><span class="line">print(arr[nonzero_indices])  # 非零元素的值 [1, 2, 3, 4]</span><br></pre></td></tr></table></div></figure>        <h4 id="3-3-numpy-extract"   >          <a href="#3-3-numpy-extract" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-3-numpy-extract" class="headerlink" title="3.3 numpy.extract()"></a>3.3 numpy.extract()</h4>      <p>根据条件从数组中抽取元素</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])</span><br><span class="line"></span><br><span class="line"># 提取偶数</span><br><span class="line">even_numbers = np.extract(arr % 2 == 0, arr)</span><br><span class="line">print(even_numbers)  # 输出 [2, 4, 6, 8]</span><br></pre></td></tr></table></div></figure>        <h3 id="4-实用排序技巧"   >          <a href="#4-实用排序技巧" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-实用排序技巧" class="headerlink" title="4. 实用排序技巧"></a>4. 实用排序技巧</h3>              <h4 id="4-1-按指定字段排序（结构化数组）"   >          <a href="#4-1-按指定字段排序（结构化数组）" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-1-按指定字段排序（结构化数组）" class="headerlink" title="4.1 按指定字段排序（结构化数组）"></a>4.1 按指定字段排序（结构化数组）</h4>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"># 创建结构化数组</span><br><span class="line">dtype = [(&#x27;name&#x27;, &#x27;U10&#x27;), (&#x27;age&#x27;, int), (&#x27;score&#x27;, float)]</span><br><span class="line">students = np.array([(&#x27;Alice&#x27;, 20, 88.5), </span><br><span class="line">                     (&#x27;Bob&#x27;, 19, 92.0), </span><br><span class="line">                     (&#x27;Charlie&#x27;, 21, 85.5)], dtype=dtype)</span><br><span class="line"></span><br><span class="line"># 按年龄排序</span><br><span class="line">sorted_by_age = np.sort(students, order=&#x27;age&#x27;)</span><br><span class="line">print(sorted_by_age)</span><br></pre></td></tr></table></div></figure>        <h4 id="4-2-分区排序-numpy-partition"   >          <a href="#4-2-分区排序-numpy-partition" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-2-分区排序-numpy-partition" class="headerlink" title="4.2 分区排序 numpy.partition()"></a>4.2 分区排序 numpy.partition()</h4>      <p>快速找到前k个最小&#x2F;最大值</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">arr = np.array([46, 57, 23, 39, 1, 10, 0, 120])</span><br><span class="line"></span><br><span class="line"># 找到第3小的值</span><br><span class="line">partitioned = np.partition(arr, 2)</span><br><span class="line">print(partitioned[2])  # 第3小的值：10</span><br><span class="line"></span><br><span class="line"># 找到第2大的值</span><br><span class="line">partitioned = np.partition(arr, -2)</span><br><span class="line">print(partitioned[-2])  # 第2大的值：57</span><br></pre></td></tr></table></div></figure>        <h3 id="5-实际应用示例"   >          <a href="#5-实际应用示例" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-实际应用示例" class="headerlink" title="5. 实际应用示例"></a>5. 实际应用示例</h3>              <h4 id="5-1-数据清洗：处理异常值"   >          <a href="#5-1-数据清洗：处理异常值" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-1-数据清洗：处理异常值" class="headerlink" title="5.1 数据清洗：处理异常值"></a>5.1 数据清洗：处理异常值</h4>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"># 生成包含异常值的测试数据</span><br><span class="line">data = np.array([1, 2, 3, 100, 4, 5, 200, 6, 7])</span><br><span class="line"></span><br><span class="line"># 使用分位数识别异常值</span><br><span class="line">Q1 = np.percentile(data, 25)</span><br><span class="line">Q3 = np.percentile(data, 75)</span><br><span class="line">IQR = Q3 - Q1</span><br><span class="line"></span><br><span class="line">lower_bound = Q1 - 1.5 * IQR</span><br><span class="line">upper_bound = Q3 + 1.5 * IQR</span><br><span class="line"></span><br><span class="line"># 筛选正常范围的数据</span><br><span class="line">normal_data = data[(data &gt;= lower_bound) &amp; (data &lt;= upper_bound)]</span><br><span class="line">print(f&quot;原始数据: &#123;data&#125;&quot;)</span><br><span class="line">print(f&quot;正常数据: &#123;normal_data&#125;&quot;)</span><br></pre></td></tr></table></div></figure>        <h4 id="5-2-成绩排名系统"   >          <a href="#5-2-成绩排名系统" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-2-成绩排名系统" class="headerlink" title="5.2 成绩排名系统"></a>5.2 成绩排名系统</h4>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"># 学生成绩数据</span><br><span class="line">scores = np.array([85, 92, 78, 96, 88, 75])</span><br><span class="line">students = np.array([&#x27;Alice&#x27;, &#x27;Bob&#x27;, &#x27;Charlie&#x27;, &#x27;David&#x27;, &#x27;Eve&#x27;, &#x27;Frank&#x27;])</span><br><span class="line"></span><br><span class="line"># 按成绩降序排列</span><br><span class="line">sorted_indices = np.argsort(-scores)  # 负号实现降序</span><br><span class="line">ranked_students = students[sorted_indices]</span><br><span class="line">ranked_scores = scores[sorted_indices]</span><br><span class="line"></span><br><span class="line">print(&quot;成绩排名:&quot;)</span><br><span class="line">for i, (student, score) in enumerate(zip(ranked_students, ranked_scores)):</span><br><span class="line">    print(f&quot;&#123;i+1&#125;. &#123;student&#125;: &#123;score&#125;分&quot;)</span><br></pre></td></tr></table></div></figure><p>这些函数是NumPy数据处理中最常用的工具，掌握它们能极大提高数据分析和处理的效率。</p>]]></content>
      
      
      <categories>
          
          <category> 数据分析 </category>
          
          <category> python </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> python </tag>
            
            <tag> numpy </tag>
            
            <tag> 数据分析 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>shell修炼手册</title>
      <link href="/2025/09/28/shell%E4%BF%AE%E7%82%BC%E6%89%8B%E5%86%8C/"/>
      <url>/2025/09/28/shell%E4%BF%AE%E7%82%BC%E6%89%8B%E5%86%8C/</url>
      
        <content type="html"><![CDATA[<p>shell的学习其实是有些反人类的，这意味着你对着的界面是<strong>单调的黑屏</strong>和<strong>一行行的代码</strong>。图形化时代一去不复返。但是同时它也是炫酷的，<strong>可以让你的工作效率大幅度增加</strong>。学习过程中作者感到有些痛苦，因为shell作为一个工具型脚本语言，并没有很具体的教程。csdiy上推荐的MIT教程应该是最好的了，推荐食用。<span class="exturl"><a class="exturl__link"   href="https://missing-semester-cn.github.io/" >附上链接</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span>。这篇文章中我会对我学到的知识，以<strong>关键词的分类方式进行总结</strong>(这样比较系统方便查找记忆)，对课上的知识点进行实际运用。</p>        <h2 id="什么是Shell"   >          <a href="#什么是Shell" class="heading-link"><i class="fas fa-link"></i></a><a href="#什么是Shell" class="headerlink" title="什么是Shell?"></a>什么是Shell?</h2>      <p>shell其实是一种<strong>脚本语言</strong>，什么是脚本语言？它又与<strong>编译语言</strong>进行区分。</p><p>我们知道有的编程语言，如c&#x2F;c++，必须在程序运行前将代码翻译成二进制形式，也就是生成可执行文件。</p><p>这个过程叫做<strong>编译</strong>,这样的编程语言叫做编译语言。</p><p>而有的编程语言，如 Shell、JavaScript、Python、PHP等，需要一边执行一边翻译，不会生成任何可执行文件，用户必须拿到源码才能运行程序。程序运行后会即时翻译，翻译完一部分执行一部分，不用等到所有代码都翻译完。 </p><p>这个过程叫做<strong>解释</strong>。这样的语言叫做解释型语言或脚本语言。</p><p>这是它的定义，那它到底能干什么？引用MIT的话说</p><blockquote><p>如今的计算机有着多种多样的交互接口让我们可以进行指令的的输入，从炫酷的图像用户界面（GUI），语音输入甚至是 AR&#x2F;VR 都已经无处不在。 这些交互接口可以覆盖 80% 的使用场景，但是它们也从根本上限制了您的操作方式——你不能点击一个不存在的按钮或者是用语音输入一个还没有被录入的指令。 为了充分利用计算机的能力，我们不得不回到最根本的方式，使用文字接口：Shell</p></blockquote>        <h2 id="如何配置shell"   >          <a href="#如何配置shell" class="heading-link"><i class="fas fa-link"></i></a><a href="#如何配置shell" class="headerlink" title="如何配置shell?"></a>如何配置shell?</h2>      <p>前人所述备矣，这里附上作者学长的<span class="exturl"><a class="exturl__link"   href="https://virgiling.wiki/03-tools/how-to-use-wsl2" >博客文章</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span>，供大家参考。</p><p>进入正题!</p>        <h2 id="课前提醒！"   >          <a href="#课前提醒！" class="heading-link"><i class="fas fa-link"></i></a><a href="#课前提醒！" class="headerlink" title="课前提醒！"></a>课前提醒！</h2>      <p>1.请确保你的环境是正确的（推荐wsl2）</p><blockquote><ol><li>本课程需要使用类 Unix shell，例如 Bash 或 ZSH。如果您在 Linux 或者 MacOS 上面完成本课程的练习，则不需要做任何特殊的操作。如果您使用的是 Windows，则您不应该使用 cmd 或是 Powershell；您可以使用 <span class="exturl"><a class="exturl__link"   href="https://docs.microsoft.com/en-us/windows/wsl/" >Windows Subsystem for Linux</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span> 或者是 Linux 虚拟机。使用 <code>echo $SHELL</code> 命令可以查看您的 shell 是否满足要求。如果打印结果为 <code>/bin/bash</code> 或 <code>/usr/bin/zsh</code> 则是可以的。</li></ol></blockquote><p>2.请在你的home中进行学习测试，在其他地方你的权限有限，如果自己添加权限可能会导致权力过大的滥用（总之就是不安全）。运行以下代码即可</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cd ~</span><br></pre></td></tr></table></div></figure>        <h2 id="echo-cat"   >          <a href="#echo-cat" class="heading-link"><i class="fas fa-link"></i></a><a href="#echo-cat" class="headerlink" title="echo &amp;&amp; cat"></a>echo &amp;&amp; cat</h2>      <p>1.echo其实类似c的printf。</p><figure class="highlight shell"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">wjy06@wjy:~$ echo &quot;hello word&quot;</span><br><span class="line">hello word</span><br></pre></td></tr></table></div></figure><p>2.那么对应c的&amp;，在shell中则是$。（解决了作者对键盘上为什么要出现美元符号的困扰）</p><figure class="highlight shell"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">wjy06@wjy:~$ name=&quot;jade&quot;</span><br><span class="line">wjy06@wjy:~$ echo &quot;My name is $name&quot;</span><br><span class="line">My name is jade</span><br></pre></td></tr></table></div></figure><p>3.我们知道c中会解析转义字符，但是echo<strong>默认不会解析</strong></p><figure class="highlight shell"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">wjy06@wjy:~$ echo &quot;Line 1\nLine 2&quot;</span><br><span class="line">Line 1\nLine 2</span><br></pre></td></tr></table></div></figure><p>4.当然如果你想用转义字符比如‘\n’进行换行也是可以的（-e）后面会展开讲解</p><figure class="highlight shell"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">wjy06@wjy:~$ echo -e &quot;Line 1\nLine 2&quot;</span><br><span class="line">Line 1</span><br><span class="line">Line 2</span><br></pre></td></tr></table></div></figure><p>5.我们知道echo不会解析转义字符，但这不意味着它不会解析特殊字符，比如上面用到的“$”，那我们不想特定字符被解析时如何避免呢？</p><p>在Shell中，<code>echo</code>命令使用 <strong>单引号（<code>&#39;</code>）</strong> 时，会 <strong>禁用所有特殊字符的解释</strong>，包括变量、转义字符和通配符（如 <code>$</code>、<code>*</code>、&#96;&#96;等）</p><figure class="highlight shell"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">wjy06@wjy:~$ echo &#x27;Hello, $USER! Today is $(date)&#x27;</span><br><span class="line">Hello, $USER! Today is $(date)</span><br></pre></td></tr></table></div></figure><p>6.echo还可以和<strong>重定向</strong>一起使用</p><p>在shell中，程序有两个主要的流，输入流和输出流。通常，程序的输入流输出流都是我们的终端。键盘作为输入，显示器作为输出。但是我们可以重定向这些流</p><p>最简单的重定向是 <code>&lt; file</code> 和 <code>&gt; file</code>。这两个命令可以将程序的输入输出流分别重定向到文件。</p><figure class="highlight bash"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">missing:~$ <span class="built_in">echo</span> hello &gt; hello.txt </span><br><span class="line"><span class="comment">#创建文件并写入内容</span></span><br><span class="line"><span class="comment">#echo hello：输出字符串 hello到标准输出（屏幕）&gt; hello.txt：将标准输出重定向到文件 hello.txt（覆盖写入）</span></span><br><span class="line">missing:~$ <span class="built_in">cat</span> hello.txt</span><br><span class="line">hello</span><br><span class="line"><span class="comment">#cat：直接读取文件内容并输出</span></span><br><span class="line">missing:~$ <span class="built_in">cat</span> &lt; hello.txt</span><br><span class="line">hello</span><br><span class="line"><span class="comment">#&lt; hello.txt：将文件 hello.txt的内容作为 cat的输入</span></span><br><span class="line">missing:~$ <span class="built_in">cat</span> &lt; hello.txt &gt; hello2.txt</span><br><span class="line">missing:~$ <span class="built_in">cat</span> hello2.txt</span><br><span class="line">hello</span><br><span class="line"><span class="comment">#通过重定向复制文件</span></span><br><span class="line"><span class="comment">#&lt; hello.txt：将 hello.txt内容作为 cat的输入</span></span><br><span class="line"><span class="comment">#&gt; hello2.txt：将 cat的输出重定向到 hello2.txt</span></span><br><span class="line"><span class="comment">#结果：创建 hello2.txt，内容与 hello.txt相同（相当于文件复制）</span></span><br></pre></td></tr></table></div></figure><p>7.echo追加写入</p><p>上面提到的 “&gt;”是覆盖写入，也就是说前面写的内容会被覆盖。当然我们也可以选择追加写入。</p><figure class="highlight bash"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">echo</span> world &gt;&gt; hello.txt  <span class="comment"># 追加内容</span></span><br><span class="line"><span class="built_in">cat</span> hello.txt</span><br><span class="line">hello</span><br><span class="line">world</span><br></pre></td></tr></table></div></figure><p>8.重定向与管道符’|‘</p><blockquote><p>使用管道（ <em>pipes</em> ），我们能够更好的利用文件重定向。 <code>|</code> 操作符允许我们将一个程序的输出和另外一个程序的输入连接起来：</p></blockquote><figure class="highlight shell"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cat &lt; hello.txt | grep &quot;hello&quot; &gt; filtered.txt</span><br></pre></td></tr></table></div></figure><ul><li>“&lt; hello.txt”:  将hello.txt的内容作为cat命令的输入（其实和cat hello.txt等效，但更明确的表达<strong>数据流向</strong>）</li><li>“| grep “hello””:  管道符将cat的输出作为grep（后续将有讲解）命令的输入，grep “hello”起到字符串筛选的作用，从输入中筛选包含字符串“hello”的行。</li><li>“&gt;filtered.txt”:    将grep的输出重定向到文件filetered.txt(覆盖写入)</li></ul><p>让我们来实例演示以下</p><figure class="highlight shell"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">echo &quot;hello world&quot; &gt;hello.txt</span><br><span class="line">echo &quot;goodbye world&quot; &gt;&gt; hello .txt</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">hello.txt内容</span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">hello world</span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">goodbye world</span></span><br><span class="line">cat &lt; hello.txt | grep &quot;hello&quot; &gt;filtered.txt</span><br><span class="line">cat filtered.txt</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">输出hello world</span> </span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">只有包含 <span class="string">&quot;hello&quot;</span> 的行被保留</span></span><br></pre></td></tr></table></div></figure>        <h2 id="cd-pwd-ls"   >          <a href="#cd-pwd-ls" class="heading-link"><i class="fas fa-link"></i></a><a href="#cd-pwd-ls" class="headerlink" title="cd &amp;&amp; pwd &amp;&amp;ls"></a>cd &amp;&amp; pwd &amp;&amp;ls</h2>      <p><strong>1.<code>cd</code>（Change Directory）</strong></p><p>是 Linux&#x2F;Unix 和 Windows 命令行中最基础且最常用的命令之一，用于切换当前工作目录。在路径中，<code>.</code> 表示的是当前目录</p><ul><li><p>切换到绝对路径（以&#x2F;开头）</p><figure class="highlight shell"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cd /usr/local/bin # 从根目录开始的完整路径</span><br></pre></td></tr></table></div></figure></li><li><p>切换到相对路径</p><figure class="highlight shell"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cd document/project #相对于当前目录</span><br></pre></td></tr></table></div></figure></li><li><p>返回上一级目录</p><figure class="highlight shell"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cd ..</span><br></pre></td></tr></table></div></figure></li><li><p>返回home目录</p><figure class="highlight shell"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cd ~</span><br></pre></td></tr></table></div></figure></li><li><p>切换到上次所在目录</p><figure class="highlight shell"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cd -</span><br></pre></td></tr></table></div></figure></li><li><p>搭配*号使用</p><figure class="highlight shell"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cd /usr/local/*/bin  # 匹配local文件夹中第一个子文件夹有bin的目录</span><br></pre></td></tr></table></div></figure></li></ul><p>2.<strong><code>pwd</code>（Print Working Directory），用于显示当前工作目录</strong></p><p>它可以打印当前所在的绝对路径（也许你cd到一个文件夹里但是不确定是不是你要找的那个，这时候pwd可以派上用场）</p><p>当我在Home环境时</p><figure class="highlight shell"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">wjy06@wjy:~$ pwd</span><br><span class="line">/home/wjy06</span><br></pre></td></tr></table></div></figure><p>注意，pwd其实默认的是pwd -L，我们还可以选择pwd -P</p><div class="table-container"><table><thead><tr><th><code>-L</code>（默认）</th><th>显示逻辑路径（包含符号链接的路径）</th></tr></thead><tbody><tr><td><code>-P</code></td><td>显示物理路径（解析所有符号链接的真实路径）</td></tr></tbody></table></div><p>插一嘴，那么你怎么知道它有哪些可选择的参数呢？<strong>(help的使用)</strong></p><figure class="highlight shell"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">wjy06@wjy:~$ pwd --help</span><br><span class="line">pwd: pwd [-LP]</span><br><span class="line">    Print the name of the current working directory.</span><br><span class="line"></span><br><span class="line">    Options:</span><br><span class="line">      -L        print the value of $PWD if it names the current working</span><br><span class="line">                directory</span><br><span class="line">      -P        print the physical directory, without any symbolic links</span><br><span class="line"></span><br><span class="line">    By default, `pwd&#x27; behaves as if `-L&#x27; were specified.</span><br><span class="line"></span><br><span class="line">    Exit Status:</span><br><span class="line">    Returns 0 unless an invalid option is given or the current directory</span><br><span class="line">    cannot be read.</span><br></pre></td></tr></table></div></figure><p>3.<strong><code>ls</code>（List Directory Contents）：列出当前目录下的文件和子目录</strong></p><p>当我在根目录时</p><figure class="highlight shell"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">wjy06@wjy:/$ ls</span><br><span class="line">bin                boot  etc   init  lib.usr-is-merged  lost+found  mnt  proc  run   sbin.usr-is-merged  srv  tmp  var</span><br><span class="line">bin.usr-is-merged  dev   home  lib   lib64              media       opt  root  sbin  snap                sys  usr</span><br></pre></td></tr></table></div></figure><p>可以看到是对应的</p><img src="../images/image-20250928104213117.png" alt="image-20250928104213117" style="zoom: 33%;" /><p>当然，ls也有着许多参数供你选择。</p><div class="table-container"><table><thead><tr><th align="left">选项</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left"><code>-l</code></td><td align="left">以长格式（详细信息）显示</td></tr><tr><td align="left"><code>-a</code></td><td align="left">显示所有文件（包括隐藏文件 <code>.file</code>）</td></tr><tr><td align="left"><code>-h</code></td><td align="left">以人类可读的格式显示文件大小（如 KB、MB）</td></tr><tr><td align="left"><code>-t</code></td><td align="left">按修改时间排序（最新修改的在前）</td></tr><tr><td align="left"><code>-r</code></td><td align="left">反向排序</td></tr><tr><td align="left"><code>-R</code></td><td align="left">递归列出子目录内容</td></tr><tr><td align="left"><code>--color</code></td><td align="left">彩色显示（默认启用）</td></tr></tbody></table></div><p> 🛑注意！ 不要轻易尝试 ls -r。如果停不下来了请按ctrl+c（当然挺炫酷的）</p><p>这些参数同样可以通过 <code>ls --help</code>获得。当然还有一个更全面的文档。那就是<strong>man</strong>，比如：</p><p><strong>man ls</strong></p><p>它会接受一个程序名作为参数，然后将它的文档（用户手册）展现给您。注意，<strong>使用 <code>q</code> 可以退出该程序</strong>。</p>        <h2 id="mkdir-touch"   >          <a href="#mkdir-touch" class="heading-link"><i class="fas fa-link"></i></a><a href="#mkdir-touch" class="headerlink" title="mkdir &amp;&amp; touch"></a>mkdir &amp;&amp; touch</h2>      <p>1.<strong><code>mkdir</code>是 Linux 和类 Unix 系统中用于创建目录（文件夹）的基础命令，其名称源于 “make directory”。</strong></p><p>它的操作很简单，如果你想在当前目录创建文件夹</p><figure class="highlight shell"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mkdir my_folder</span><br></pre></td></tr></table></div></figure><p>如果你想在某个特定路径创建目录，可以使用</p><figure class="highlight shell"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mkdir /tmp/missing</span><br></pre></td></tr></table></div></figure><p>当然它还有许多扩展应用来满足更复杂的需求</p><div class="table-container"><table><thead><tr><th align="left">选项</th><th align="left">说明</th><th align="left">示例</th></tr></thead><tbody><tr><td align="left"><code>-p</code></td><td align="left"><strong>递归创建目录</strong>：如果路径中的父目录不存在，系统会自动创建它们。这在需要创建多层嵌套目录时特别有用。</td><td align="left"><code>mkdir -p project/docs/images</code>会一次性创建 <code>project</code>、<code>project/docs</code>和 <code>project/docs/images</code>多级目录。</td></tr><tr><td align="left"><code>-m</code></td><td align="left"><strong>设置目录权限</strong>：在创建目录时直接指定其访问权限，而无需事后使用 <code>chmod</code>命令修改。</td><td align="left"><code>mkdir -m 755 secure_dir</code>会创建一个所有者拥有读、写、执行权限，其他用户拥有读和执行权限的目录。权限模式通常用八进制数表示（如 <code>755</code>, <code>644</code>）。</td></tr><tr><td align="left"><code>-v</code></td><td align="left"><strong>显示操作详情</strong>：让命令输出它正在执行的操作信息，对于脚本调试或确认操作结果很有帮助。</td><td align="left"><code>mkdir -v new_dir</code>可能会输出 <code>mkdir: created directory &#39;new_dir&#39;</code>。</td></tr></tbody></table></div><p><strong>2.<code>touch</code>是 Linux 和类 Unix 系统中一个非常实用的命令行工具，主要功能是创建空文件和更新文件的时间戳</strong></p><p>touch命令最直接的用途是快速创建一个或多个文件，</p><p>创建单个文件</p><figure class="highlight shell"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">touch filename.txt</span><br></pre></td></tr></table></div></figure><p>创建多个文件(允许不同类型)</p><figure class="highlight shell"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">touch file1.txt file2.txt file3.md</span><br></pre></td></tr></table></div></figure>        <h5 id="⏰-核心功能：管理文件时间戳"   >          <a href="#⏰-核心功能：管理文件时间戳" class="heading-link"><i class="fas fa-link"></i></a><a href="#⏰-核心功能：管理文件时间戳" class="headerlink" title="⏰ 核心功能：管理文件时间戳"></a>⏰ 核心功能：管理文件时间戳</h5>      <p>文件在 Linux 系统中通常包含三种时间属性（可使用 <code>stat</code>命令查看）</p><ul><li><strong>访问时间 (Access Time, atime)</strong>：文件最后一次被读取的时间。</li><li><strong>修改时间 (Modification Time, mtime)</strong>：文件内容最后一次被修改的时间。</li><li><strong>变更时间 (Change Time, ctime)</strong>：文件元数据（如权限、所有者）最后一次被改变的时间。<code>touch</code>命令默认影响的是 <strong>atime</strong> 和 <strong>mtime</strong></li></ul><p>通过不同的选项，可以精确控制要更新的时间：</p><div class="table-container"><table><thead><tr><th align="left">选项</th><th align="left">作用</th></tr></thead><tbody><tr><td align="left"><code>-a</code></td><td align="left">只更新文件的<strong>访问时间</strong>。</td></tr><tr><td align="left"><code>-m</code></td><td align="left">只更新文件的<strong>修改时间</strong>。</td></tr><tr><td align="left">（无选项）</td><td align="left">同时更新文件的<strong>访问和修改时间</strong>（此为默认行为）。</td></tr></tbody></table></div>]]></content>
      
      
      <categories>
          
          <category> csdiy实验 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> csdiy </tag>
            
            <tag> shell </tag>
            
            <tag> 计算机工具 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>碎碎念</title>
      <link href="/2025/09/25/%E7%A2%8E%E7%A2%8E%E5%BF%B5/"/>
      <url>/2025/09/25/%E7%A2%8E%E7%A2%8E%E5%BF%B5/</url>
      
        <content type="html"><![CDATA[<p>好想死啊为什么GitHub都是英文。（好业余的吐槽，当时是出于什么心情？）</p><p>有时候自己之前看不上的书，读了之后发现受益匪浅，才惊觉自己从前的浅薄。推荐《先学会爱自己，再遇见对的你》这本书。如何认识自己是无数人一生都要学习的课题啊。</p><p>后悔这学期七门专业课了</p>]]></content>
      
      
      <categories>
          
          <category> 创作 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> 随笔 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>福建省赛</title>
      <link href="/2025/09/24/2025%E7%A6%8F%E5%BB%BA%E7%9C%81%E8%B5%9B/"/>
      <url>/2025/09/24/2025%E7%A6%8F%E5%BB%BA%E7%9C%81%E8%B5%9B/</url>
      
        <content type="html"><![CDATA[]]></content>
      
      
      <categories>
          
          <category> 算法 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> 算法 </tag>
            
            <tag> acm </tag>
            
            <tag> 数据结构 </tag>
            
            <tag> 栈与队列 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>打表打表</title>
      <link href="/2025/09/24/%E6%89%93%E8%A1%A8%E6%89%93%E8%A1%A8/"/>
      <url>/2025/09/24/%E6%89%93%E8%A1%A8%E6%89%93%E8%A1%A8/</url>
      
        <content type="html"><![CDATA[<p>你总会遇见很多题目，看着有点逻辑，但是数学推导非常难受。看着有点规律，但是样例太少无法确定。或者你很肯定的能给出暴力做法，但是卡你时间复杂度。</p><p>这些种种情况，我们都可以用到打表！打表一般用到的就是暴力循环，暴力判断，dfs bfs。（这里将不定时更新作者遇到的有趣的打表题）</p>        <h2 id="什么是打表？"   >          <a href="#什么是打表？" class="heading-link"><i class="fas fa-link"></i></a><a href="#什么是打表？" class="headerlink" title="什么是打表？"></a>什么是打表？</h2>      <p><strong>我们先说说狭义的打表（仅代表个人理解）</strong></p><p>打表就是将所有输入情况的答案保存在代码中，输入数据后直接输出就可以了</p><p>打表法具有快速，易行（可以写暴力枚举程序）的特点，缺点是代码可能太大，或者情况覆盖不完</p><p>对于不会超时，数据规模适合打表，为了简洁你也可以打表。</p><p><span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/P1149" >比如这道题</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p><p>这道题n&lt;&#x3D;20完全可以打表</p><p>只要你得出每个数字需要多少个火柴，问题就简单了。而不管几位的数字都是</p><figure class="highlight c"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> a[<span class="number">10</span>]=&#123;<span class="number">6</span>,<span class="number">2</span>,<span class="number">5</span>,<span class="number">5</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">3</span>,<span class="number">7</span>,<span class="number">6</span>&#125;</span><br></pre></td></tr></table></div></figure><p>这就是0-9需要的火柴数量。往后以此类推，10需要一个1和一个0。11需要两个1，也就是说我们一位位拆分即可。</p><figure class="highlight c++"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line"><span class="built_in">freopen</span>(<span class="string">&quot;ans.txt&quot;</span>,<span class="string">&quot;w&quot;</span>,stdout);</span><br><span class="line"><span class="type">int</span> a[<span class="number">10</span>]=&#123;<span class="number">6</span>,<span class="number">2</span>,<span class="number">5</span>,<span class="number">5</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">3</span>,<span class="number">7</span>,<span class="number">6</span>&#125;;</span><br><span class="line"><span class="type">int</span> i,j,temp=<span class="number">0</span>,num=<span class="number">0</span>,k,in[<span class="number">2020</span>],n;</span><br><span class="line">in[<span class="number">0</span>]=<span class="number">6</span>;</span><br><span class="line"><span class="keyword">for</span>(i=<span class="number">1</span>;i&lt;=<span class="number">2000</span>;i++)&#123;</span><br><span class="line">k=i;</span><br><span class="line">temp=<span class="number">0</span>;</span><br><span class="line"><span class="keyword">while</span>(k)&#123;</span><br><span class="line">temp+=a[k%<span class="number">10</span>];</span><br><span class="line">k/=<span class="number">10</span>;</span><br><span class="line">&#125;</span><br><span class="line">in[i]=temp;</span><br><span class="line">&#125;</span><br><span class="line">n=<span class="number">0</span>;</span><br><span class="line">Again:</span><br><span class="line">num=<span class="number">0</span>;</span><br><span class="line"><span class="keyword">for</span>(i=<span class="number">0</span>;i&lt;=<span class="number">999</span>;i++)&#123;</span><br><span class="line"><span class="keyword">for</span>(j=<span class="number">0</span>;j&lt;=<span class="number">999</span>;j++)&#123;</span><br><span class="line"><span class="keyword">if</span>(n==in[i]+in[j]+in[i+j]<span class="number">+4</span>) num++;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">&quot;%d,&quot;</span>,num);</span><br><span class="line"><span class="keyword">if</span>(n&lt;<span class="number">24</span>)&#123;n++;<span class="keyword">goto</span> Again;&#125;</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>然后得到答案你就可以这样，面向答案编程</p><figure class="highlight c++"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">int</span> ans[]=&#123;<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">8</span>,<span class="number">9</span>,<span class="number">6</span>,<span class="number">9</span>,<span class="number">29</span>,<span class="number">39</span>,<span class="number">38</span>,<span class="number">65</span>,<span class="number">88</span>,<span class="number">128</span>&#125;;</span><br><span class="line"><span class="type">int</span> n;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">cin&gt;&gt;n;</span><br><span class="line">cout&lt;&lt;ans[n]&lt;&lt;<span class="string">&#x27;\n&#x27;</span>;</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>也许这道题你还没有领略到打表的方便之处。</p><p><span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/P2657" >试试这道题</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p><p>数位dp题，你也许会觉得难。但是没关系，我们提供更暴力更简单的方法。</p><figure class="highlight c++"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;cstdio&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;algorithm&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;cmath&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> For(i,a,b) for(int (i)=(a);(i)&lt;=(b);(i)++)</span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N=<span class="number">1e6</span><span class="number">+5</span>;</span><br><span class="line"><span class="type">int</span> ans,a,b,sum[<span class="number">2005</span>]=&#123;<span class="number">0</span>, <span class="number">202174</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138252</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138214</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">138503</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">136131</span>, <span class="number">155315</span>, <span class="number">155315</span>, <span class="number">136131</span>, <span class="number">138503</span>, <span class="number">138214</span>, <span class="number">138252</span>, <span class="number">138252</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">155315</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>&#125;;</span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="type">void</span> <span class="title">check</span><span class="params">(<span class="type">int</span> x)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(x&lt;=<span class="number">9</span>)&#123;ans++;<span class="keyword">return</span>;&#125;</span><br><span class="line">    <span class="type">int</span> a=x,b=<span class="number">-5</span>;</span><br><span class="line">    <span class="keyword">while</span>(a)&#123;</span><br><span class="line">        <span class="keyword">if</span>(<span class="built_in">abs</span>(a%<span class="number">10</span>-b)&lt;<span class="number">2</span>)<span class="keyword">return</span>;</span><br><span class="line">        b=a%<span class="number">10</span>;a=a/<span class="number">10</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    ans++;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    cin&gt;&gt;a&gt;&gt;b;</span><br><span class="line">    <span class="keyword">if</span>(b-a&lt;=<span class="number">1000000</span>)&#123;</span><br><span class="line">        <span class="built_in">For</span>(i,a,b)<span class="built_in">check</span>(i);</span><br><span class="line">        cout&lt;&lt;ans;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="type">int</span> p=<span class="built_in">ceil</span>(a*<span class="number">1.0</span>/<span class="number">1000000</span>),q=<span class="built_in">floor</span>(b*<span class="number">1.0</span>/<span class="number">1000000</span>);</span><br><span class="line">    <span class="built_in">For</span>(i,<span class="number">1</span>,<span class="number">2000</span>)sum[i]+=sum[i<span class="number">-1</span>];</span><br><span class="line">    ans+=sum[q]-sum[p];</span><br><span class="line">    <span class="keyword">if</span>(!ans)ans++;</span><br><span class="line">    p=p*<span class="number">1000000</span>,q=q*<span class="number">1000000</span>;</span><br><span class="line">    <span class="keyword">if</span>(a!=p)</span><br><span class="line">    <span class="built_in">For</span>(i,a,p<span class="number">-1</span>)<span class="built_in">check</span>(i);</span><br><span class="line">    <span class="keyword">if</span>(b!=q)</span><br><span class="line">    <span class="built_in">For</span>(i,q<span class="number">+1</span>,b)<span class="built_in">check</span>(i);</span><br><span class="line">    cout&lt;&lt;ans;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br></pre></td></tr></table></div></figure><p>这里引用了<span class="exturl"><a class="exturl__link"   href="https://www.cnblogs.com/five20/p/9040490.html" >five20</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span>的代码。由于过于暴力我们就不多解释了。这一长串数组就是打表打出来的。然后直接暴力筛选。</p>        <h2 id="打表真的有用吗？"   >          <a href="#打表真的有用吗？" class="heading-link"><i class="fas fa-link"></i></a><a href="#打表真的有用吗？" class="headerlink" title="打表真的有用吗？"></a>打表真的有用吗？</h2>      <p>有的朋友。也许我们不能遇见上面这些及其粗暴的方法能写的题目。但是往往我们可以找到很多答案来寻找规律。<strong>这就是我理解的广义的打表。</strong></p><p><span class="exturl"><a class="exturl__link"   href="https://codeforces.com/gym/105588/problem/M" >可以看看这道题</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p><p>题意：构造一个矩阵，使相邻两个数之和两两不重复。</p><p>刚拿到这道题目的你是不是有点摸不着头脑？</p><p>这很明显你不能很暴力的来遍历拿到一个矩阵，所以我们需要找到某种特殊的方式，让我们按照这个方式构造出的矩阵一定相邻两个数之和不重复。</p><p>这时候我们不妨打表。注释写在代码上了。</p><p>原理就是尝试填充一个 <code>n x m</code>的矩阵，使得矩阵中相邻元素的和都是唯一的。如果找到这样的填充方式，它会输出该矩阵。</p><figure class="highlight c++"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">int</span> a[<span class="number">1005</span>][<span class="number">1005</span>];</span><br><span class="line"><span class="type">int</span> n,m;</span><br><span class="line"><span class="type">int</span> tot=<span class="number">0</span>;</span><br><span class="line"><span class="type">bool</span> vis[<span class="number">10000</span>];</span><br><span class="line"><span class="function"><span class="type">bool</span> <span class="title">check</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    set&lt;<span class="type">int</span>&gt;s;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">1</span>;i&lt;=n<span class="number">-1</span>;i++)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> j=<span class="number">1</span>;j&lt;=m<span class="number">-1</span>;j++)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">if</span>(s.<span class="built_in">count</span>(a[i][j]+a[i<span class="number">+1</span>][j]))  <span class="comment">// 检查当前元素和下方元素的和</span></span><br><span class="line">            &#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span>(s.<span class="built_in">count</span>(a[i][j]+a[i][j<span class="number">+1</span>]))  <span class="comment">// 检查当前元素和右方元素的和</span></span><br><span class="line">            &#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            s.<span class="built_in">insert</span>(a[i][j]+a[i][j<span class="number">+1</span>]);    <span class="comment">// 插入当前元素和右方元素的和</span></span><br><span class="line">            s.<span class="built_in">insert</span>(a[i][j]+a[i<span class="number">+1</span>][j]);    <span class="comment">// 插入当前元素和下方元素的和</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 检查最后一列的元素和下方元素的和</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">1</span>;i&lt;=n<span class="number">-1</span>;i++)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span>(s.<span class="built_in">count</span>(a[i][m]+a[i<span class="number">+1</span>][m]))<span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        s.<span class="built_in">insert</span>(a[i][m]+a[i<span class="number">+1</span>][m]);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 检查最后一行的元素和右方元素的和</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">1</span>;i&lt;=m<span class="number">-1</span>;i++)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span>(s.<span class="built_in">count</span>(a[n][i]+a[n][i<span class="number">+1</span>]))<span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        s.<span class="built_in">insert</span>(a[n][i]+a[n][i<span class="number">+1</span>]);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">dfs</span><span class="params">(<span class="type">int</span> dep)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    tot++;</span><br><span class="line">    <span class="keyword">if</span>(dep==n*m<span class="number">+1</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span>(<span class="built_in">check</span>())</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">1</span>;i&lt;=n;i++)</span><br><span class="line">            &#123;</span><br><span class="line">                <span class="keyword">for</span>(<span class="type">int</span> j=<span class="number">1</span>;j&lt;=m;j++)</span><br><span class="line">                &#123;</span><br><span class="line">                    cout &lt;&lt;a[i][j]&lt;&lt;<span class="string">&quot; &quot;</span>;</span><br><span class="line">                &#125;</span><br><span class="line">                cout&lt;&lt;endl;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">1</span>;i&lt;=n*m;i++)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span>(vis[i]) <span class="keyword">continue</span>;  <span class="comment">// 如果数字i已经被使用，跳过</span></span><br><span class="line">        vis[i]=<span class="number">1</span>;             <span class="comment">// 标记数字i为已使用</span></span><br><span class="line">        <span class="type">int</span> hang;</span><br><span class="line">        <span class="keyword">if</span>(tot%m==<span class="number">0</span>)hang=tot/m;</span><br><span class="line">        <span class="keyword">else</span> hang=tot/m<span class="number">+1</span>;</span><br><span class="line">        <span class="type">int</span> lie=tot%m;</span><br><span class="line">        <span class="keyword">if</span>(lie==<span class="number">0</span>)lie=m;</span><br><span class="line">        a[hang][lie]=i;       <span class="comment">// 将数字i放入矩阵的当前位置</span></span><br><span class="line">        <span class="built_in">dfs</span>(dep<span class="number">+1</span>);           <span class="comment">// 递归填充下一个位置</span></span><br><span class="line">        a[hang][lie]=<span class="number">-1</span>;      <span class="comment">// 回溯：恢复矩阵的当前位置</span></span><br><span class="line">        tot--;                <span class="comment">// 回溯：恢复tot</span></span><br><span class="line">        vis[i]=<span class="number">0</span>;             <span class="comment">// 回溯：恢复数字i的标记</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="type">int</span> t;</span><br><span class="line">    cin &gt;&gt;t;</span><br><span class="line">    <span class="keyword">while</span>(t--)</span><br><span class="line">    &#123;</span><br><span class="line">        cin &gt;&gt;n&gt;&gt;m;</span><br><span class="line">        <span class="built_in">dfs</span>(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p> 打表出来我们发现一个规律</p><p>如果是奇数行那不动，偶数行循环右移一位即可（不要问我循环右移是什么）</p><figure class="highlight c++"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="meta">#<span class="keyword">define</span> int long long </span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> asd(i,a,b) for(int i=a;i&lt;=b;i++)</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> des(i,a,b) for(int i=a;i&gt;=b;i--)</span></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N=<span class="number">2e5</span><span class="number">+7</span>,inf=<span class="number">2e18</span>,mod=<span class="number">998244353</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">solve</span><span class="params">()</span></span>&#123;</span><br><span class="line">    <span class="type">int</span> n,m;cin&gt;&gt;n&gt;&gt;m;</span><br><span class="line">    cout&lt;&lt;<span class="string">&quot;Yes&quot;</span>&lt;&lt;endl;</span><br><span class="line">    <span class="keyword">if</span>(m&amp;<span class="number">1</span>)&#123;</span><br><span class="line">        <span class="type">int</span> cnt=<span class="number">0</span>;</span><br><span class="line">        <span class="built_in">asd</span>(i,<span class="number">1</span>,n)&#123;</span><br><span class="line">            <span class="keyword">if</span>(i&amp;<span class="number">1</span>)&#123;</span><br><span class="line">                <span class="built_in">asd</span>(j,<span class="number">1</span>,m)cout&lt;&lt;++cnt&lt;&lt;<span class="string">&quot; &quot;</span>;</span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                <span class="type">int</span> tmp=++cnt;</span><br><span class="line"></span><br><span class="line">                <span class="built_in">asd</span>(j,<span class="number">2</span>,m)cout&lt;&lt;++cnt&lt;&lt;<span class="string">&quot; &quot;</span>;</span><br><span class="line">                cout&lt;&lt;tmp&lt;&lt;<span class="string">&quot; &quot;</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            cout&lt;&lt;endl;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">        <span class="type">int</span> cnt=<span class="number">0</span>;</span><br><span class="line">        <span class="built_in">asd</span>(i,<span class="number">1</span>,n)&#123;</span><br><span class="line">            <span class="built_in">asd</span>(j,<span class="number">1</span>,m)cout&lt;&lt;++cnt&lt;&lt;<span class="string">&quot; &quot;</span>;</span><br><span class="line">            cout&lt;&lt;endl;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="type">signed</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    ios::<span class="built_in">sync_with_stdio</span>(<span class="number">0</span>),cin.<span class="built_in">tie</span>(<span class="number">0</span>),cout.<span class="built_in">tie</span>(<span class="number">0</span>);</span><br><span class="line">    <span class="type">int</span> t=<span class="number">1</span>;</span><br><span class="line">    cin&gt;&gt;t;</span><br><span class="line">    <span class="keyword">while</span>(t--)&#123;</span><br><span class="line">        <span class="built_in">solve</span>();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>附上代码。</p>]]></content>
      
      
      <categories>
          
          <category> 算法 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> 算法 </tag>
            
            <tag> acm </tag>
            
            <tag> 数据结构 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>栈与队列入门</title>
      <link href="/2025/09/24/%E6%A0%88%E4%B8%8E%E9%98%9F%E5%88%97/"/>
      <url>/2025/09/24/%E6%A0%88%E4%B8%8E%E9%98%9F%E5%88%97/</url>
      
        <content type="html"><![CDATA[        <h2 id="什么是栈？"   >          <a href="#什么是栈？" class="heading-link"><i class="fas fa-link"></i></a><a href="#什么是栈？" class="headerlink" title="什么是栈？"></a>什么是栈？</h2>      <p><stack>是C++标准库（STL）的一部分，它实现了一个<strong>先进后出</strong>的数据结构，它适用于最后添加的元素先被移除的场景。</p><img src="../images/48bbb505af53405bb72df29944601cf7.png" alt="【C++】STL：栈和队列模拟实现_堆栈模拟队列c++-CSDN博客" style="zoom:33%;" />        <h2 id="栈的基本操作有哪些？"   >          <a href="#栈的基本操作有哪些？" class="heading-link"><i class="fas fa-link"></i></a><a href="#栈的基本操作有哪些？" class="headerlink" title="栈的基本操作有哪些？"></a>栈的基本操作有哪些？</h2>      <ul><li><p>push():在栈顶添加一个元素</p></li><li><p>pop():弹出栈顶元素</p></li><li><p>top():返回栈顶元素的引用但不移除它</p></li><li><p>empty():检查栈是否为空</p></li><li><p>size():返回栈中元素的数量</p><p>这里是栈的基本语法</p></li></ul><figure class="highlight c++"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stack&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    std::stack&lt;<span class="type">int</span>&gt; s;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 向栈中添加元素</span></span><br><span class="line">    s.<span class="built_in">push</span>(<span class="number">1</span>);</span><br><span class="line">    s.<span class="built_in">push</span>(<span class="number">2</span>);</span><br><span class="line">    s.<span class="built_in">push</span>(<span class="number">3</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 访问栈顶元素</span></span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;Top element is: &quot;</span> &lt;&lt; s.<span class="built_in">top</span>() &lt;&lt; std::endl;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 移除栈顶元素</span></span><br><span class="line">    s.<span class="built_in">pop</span>();</span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;After popping, top element is: &quot;</span> &lt;&lt; s.<span class="built_in">top</span>() &lt;&lt; std::endl;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 检查栈是否为空</span></span><br><span class="line">    <span class="keyword">if</span> (!s.<span class="built_in">empty</span>()) &#123;</span><br><span class="line">        std::cout &lt;&lt; <span class="string">&quot;Stack is not empty.&quot;</span> &lt;&lt; std::endl;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 打印栈的大小</span></span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;Size of stack: &quot;</span> &lt;&lt; s.<span class="built_in">size</span>() &lt;&lt; std::endl;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h3 id="注意事项"   >          <a href="#注意事项" class="heading-link"><i class="fas fa-link"></i></a><a href="#注意事项" class="headerlink" title="注意事项"></a>注意事项</h3>      <ul><li><p><code>&lt;stack&gt;</code> 不提供直接访问栈中元素的方法，只能通过 <code>top()</code> 访问栈顶元素。</p></li><li><p>尝试在空栈上调用 <code>top()</code> 或 <code>pop()</code> 将导致未定义行为。</p></li><li><p><code>&lt;stack&gt;</code> 的底层容器可以是任何支持随机访问迭代器的序列容器，如 <code>vector</code> 或 <code>deque</code>。</p></li></ul>        <h2 id="什么是队列？"   >          <a href="#什么是队列？" class="heading-link"><i class="fas fa-link"></i></a><a href="#什么是队列？" class="headerlink" title="什么是队列？"></a>什么是队列？</h2>      <p>C++ 标准库中的 <code>&lt;queue&gt;</code> 头文件提供了队列（Queue）数据结构的实现。队列是一种<strong>先进先出</strong>（FIFO, First In First Out）的数据结构，它允许在<strong>一端添加元素</strong>（称为队尾），<strong>并在另一端移除元素</strong>（称为队首）。</p><p>队列是一种线性数据结构，它遵循以下规则：</p><ul><li><strong>元素只能从队尾添加。</strong></li><li><strong>元素只能从队首移除。</strong></li></ul>        <h2 id="队列有哪些常用操作？"   >          <a href="#队列有哪些常用操作？" class="heading-link"><i class="fas fa-link"></i></a><a href="#队列有哪些常用操作？" class="headerlink" title="队列有哪些常用操作？"></a>队列有哪些常用操作？</h2>      <p>队列提供了以下常用操作：</p><ul><li><code>empty()</code>: 检查队列是否为空。</li><li><code>size()</code>: 返回队列中的元素数量。</li><li><code>front()</code>: 返回队首元素的引用。</li><li><code>back()</code>: 返回队尾元素的引用。（栈就无法返回最底下的元素）</li><li><code>push()</code>: 在队尾添加一个元素。</li><li><code>pop()</code>: 移除队首元素。</li></ul><p>简单实例如下</p><figure class="highlight c++"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;queue&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 创建一个整数队列</span></span><br><span class="line">    std::queue&lt;<span class="type">int</span>&gt; q;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 向队列中添加元素</span></span><br><span class="line">    q.<span class="built_in">push</span>(<span class="number">10</span>);</span><br><span class="line">    q.<span class="built_in">push</span>(<span class="number">20</span>);</span><br><span class="line">    q.<span class="built_in">push</span>(<span class="number">30</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 打印队列中的元素数量</span></span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;队列中的元素数量: &quot;</span> &lt;&lt; q.<span class="built_in">size</span>() &lt;&lt; std::endl;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 打印队首元素</span></span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;队首元素: &quot;</span> &lt;&lt; q.<span class="built_in">front</span>() &lt;&lt; std::endl;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 打印队尾元素</span></span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;队尾元素: &quot;</span> &lt;&lt; q.<span class="built_in">back</span>() &lt;&lt; std::endl;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 移除队首元素</span></span><br><span class="line">    q.<span class="built_in">pop</span>();</span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;移除队首元素后，队首元素: &quot;</span> &lt;&lt; q.<span class="built_in">front</span>() &lt;&lt; std::endl;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 再次打印队列中的元素数量</span></span><br><span class="line">    std::cout &lt;&lt; <span class="string">&quot;队列中的元素数量: &quot;</span> &lt;&lt; q.<span class="built_in">size</span>() &lt;&lt; std::endl;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>以上总结参考<span class="exturl"><a class="exturl__link"   href="https://www.runoob.com/" >菜鸟驿站</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span>和<span class="exturl"><a class="exturl__link"   href="https://oi-wiki.org/" >OIWIKI</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>        <h2 id="栈实战环节1（括号匹配）"   >          <a href="#栈实战环节1（括号匹配）" class="heading-link"><i class="fas fa-link"></i></a><a href="#栈实战环节1（括号匹配）" class="headerlink" title="栈实战环节1（括号匹配）"></a>栈实战环节1（括号匹配）</h2>      <p>现在我们来写一道<span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/P1739" >经典队列入门题</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span>，括号匹配。</p><p>当年作者写这道题目的时候不懂数据结构，自己想了个取巧的方法。现在来看真是感慨。</p><figure class="highlight c++"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="type">int</span> temp1 = <span class="number">0</span>, temp2 = <span class="number">0</span>, mark1 = <span class="number">0</span>, mark2 = <span class="number">0</span>, n, x = <span class="number">0</span>, y = <span class="number">0</span>;</span><br><span class="line">    string a;</span><br><span class="line">    <span class="type">int</span> left[<span class="number">1000</span>];</span><br><span class="line">    <span class="type">int</span> right[<span class="number">1000</span>];</span><br><span class="line">    cin &gt;&gt; a;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; a.<span class="built_in">length</span>() &amp;&amp; a[i] != <span class="string">&#x27;@&#x27;</span>; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (a[i] == <span class="string">&#x27;(&#x27;</span>) &#123;</span><br><span class="line">            left[temp1] = i;</span><br><span class="line">            temp1++;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">0</span>; j &lt; a.<span class="built_in">length</span>() &amp;&amp; a[j] != <span class="string">&#x27;@&#x27;</span>; j++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (a[j] == <span class="string">&#x27;)&#x27;</span>) &#123;</span><br><span class="line">            right[temp2] = j;</span><br><span class="line">            temp2++;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (temp1 != temp2) &#123;</span><br><span class="line">        x = <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>;i &lt; temp1 &amp;&amp; x==<span class="number">0</span>; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (left[i] &gt; right[i])</span><br><span class="line">            y = <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (x == <span class="number">0</span> &amp;&amp; y == <span class="number">0</span>) &#123;</span><br><span class="line">        cout &lt;&lt; <span class="string">&quot;YES&quot;</span>;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        cout &lt;&lt; <span class="string">&quot;NO&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></div></figure><p>把左右括号的坐标用两个数组存下来。然后去比对。不管思路和时间复杂度怎样，代码还是相对简洁的啊！</p><p>那么我们现在尝试用栈。思路很简单，遍历字符串。</p><ul><li><p>遇到 <code>(</code>压入栈 <code>st</code>。</p></li><li><p>遇到 <code>)</code>时：</p><ul><li>如果栈为空，输出 “NO” 并结束程序。（这时候已经不合法了）</li><li>否则弹出栈顶的 <code>(</code>。（括号成功匹配）</li></ul></li><li><p>遍历结束后，如果栈为空，说明所有 <code>(</code>都有对应的 <code>)</code>，输出 “YES”。</p></li><li><p>否则输出 “NO”。（不为空说明“（”太多啦）</p><p>贴上AC代码</p></li></ul><figure class="highlight c++"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    stack&lt;<span class="type">int</span>&gt; a;</span><br><span class="line">    string s;</span><br><span class="line">    cin &gt;&gt; s;</span><br><span class="line">    <span class="type">int</span> pos = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; s.<span class="built_in">length</span>(); i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (s[i] == <span class="string">&#x27;@&#x27;</span>) &#123;</span><br><span class="line">            pos = i;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt;= pos; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (s[i] == <span class="string">&#x27;(&#x27;</span>) &#123;</span><br><span class="line">            a.<span class="built_in">push</span>(s[i]);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(s[i]==<span class="string">&#x27;)&#x27;</span>) &#123;</span><br><span class="line">            <span class="keyword">if</span>(a.<span class="built_in">empty</span>()) &#123;</span><br><span class="line">                cout &lt;&lt;<span class="string">&quot;NO&quot;</span>;</span><br><span class="line">                <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span> &#123;</span><br><span class="line">                a.<span class="built_in">pop</span>();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (a.<span class="built_in">empty</span>()) &#123;</span><br><span class="line">        cout &lt;&lt; <span class="string">&quot;YES&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">        cout &lt;&lt; <span class="string">&quot;NO&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></div></figure>        <h2 id="栈实战环节2（表达式）"   >          <a href="#栈实战环节2（表达式）" class="heading-link"><i class="fas fa-link"></i></a><a href="#栈实战环节2（表达式）" class="headerlink" title="栈实战环节2（表达式）"></a>栈实战环节2（表达式）</h2>      <p><span class="exturl"><a class="exturl__link"   href="https://www.luogu.com.cn/problem/P1981" >洛谷普及难度题目</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p><p>一打眼其实这是一道小模拟的题目。那么我们开始模拟吧。</p><p><code>1+1*3+4</code></p><p>对于这个样例，我们会怎么计算呢。我们往往想的是，先把带乘法的都算完，然后最后只剩加法来相加。比如这个算式我们肯定会先计算1*3得出3之后，把式子转为1+3+4。思路很简单，那么代码如何实现呢。</p><p>按照我们朴素的思路，应该就是查找<code>“*”</code>两边的数字位置。那么思路就出来了，首先用字符串的方式来读入，然后遍历字符串，找到乘号的位置，然后往前往后遍历寻找到相邻的符号，把符号间的数字提取出来。计算出结果后，再用计算结果替代原字符串。最后把乘号都替换完只剩下加号的时候再遍历一遍相加。</p><p><strong>你是不是晕了？</strong></p><p>你确实该晕。因为实现代码实在是太复杂啦！(这里附上代码，但是不是为了让你学习，只是让你看看这有多麻烦)</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;string&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> MOD = <span class="number">10000</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    string expr;</span><br><span class="line">    cin &gt;&gt; expr;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 先处理所有乘法</span></span><br><span class="line">    <span class="type">size_t</span> pos;</span><br><span class="line">    <span class="keyword">while</span> ((pos = expr.<span class="built_in">find</span>(<span class="string">&#x27;*&#x27;</span>)) != string::npos) &#123;</span><br><span class="line">        <span class="comment">// 找到 * 左边的数字的起始位置</span></span><br><span class="line">        <span class="type">size_t</span> left_start = pos;</span><br><span class="line">        <span class="keyword">while</span> (left_start &gt; <span class="number">0</span> &amp;&amp; <span class="built_in">isdigit</span>(expr[left_start - <span class="number">1</span>])) &#123;</span><br><span class="line">            left_start--;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 找到 * 右边的数字的结束位置</span></span><br><span class="line">        <span class="type">size_t</span> right_end = pos;</span><br><span class="line">        <span class="keyword">while</span> (right_end + <span class="number">1</span> &lt; expr.<span class="built_in">size</span>() &amp;&amp; <span class="built_in">isdigit</span>(expr[right_end + <span class="number">1</span>])) &#123;</span><br><span class="line">            right_end++;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 提取左右数字</span></span><br><span class="line">        <span class="type">int</span> left_num = <span class="built_in">stoi</span>(expr.<span class="built_in">substr</span>(left_start, pos - left_start));</span><br><span class="line">        <span class="type">int</span> right_num = <span class="built_in">stoi</span>(expr.<span class="built_in">substr</span>(pos + <span class="number">1</span>, right_end - pos));</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 计算乘积并取模</span></span><br><span class="line">        <span class="type">int</span> product = (left_num * right_num) % MOD;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 替换原字符串中的部分</span></span><br><span class="line">        expr.<span class="built_in">replace</span>(left_start, right_end - left_start + <span class="number">1</span>, <span class="built_in">to_string</span>(product));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 现在只剩下加法，直接计算总和</span></span><br><span class="line">    <span class="type">int</span> result = <span class="number">0</span>;</span><br><span class="line">    <span class="type">size_t</span> start = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span> (start &lt; expr.<span class="built_in">size</span>()) &#123;</span><br><span class="line">        <span class="type">size_t</span> end = expr.<span class="built_in">find</span>(<span class="string">&#x27;+&#x27;</span>, start);</span><br><span class="line">        <span class="keyword">if</span> (end == string::npos) &#123;</span><br><span class="line">            end = expr.<span class="built_in">size</span>();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">int</span> num = <span class="built_in">stoi</span>(expr.<span class="built_in">substr</span>(start, end - start));</span><br><span class="line">        result = (result + num) % MOD;</span><br><span class="line">        start = end + <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    cout &lt;&lt; result &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p><strong>虽然说我们是模拟，但是也不能完全模拟</strong>。因为你要按照计算机更好实现的方式来模拟。</p><p>这个思路最大的问题在于，它用string手动存储了整个表达式，手动解析了运算符号。非常依赖字符串索引。</p><p>这是不会利用<strong>cin</strong>的表现。cin&gt;&gt;t可以直接读取一个整数，跳过空格和换行符。cin &gt;&gt;c可以读取一个字符。</p><p>所以你可以根据c++的输入流自动处理数字和运算符。达到边输入边计算的效果。</p><p><code>1+1*3+4</code>  <code>1*5+3*6</code></p><p>我们再看几个例子，那我们按照计算机的输入方法从左往右看。第一个数字是1，然后接着的运算符是“+”，那显然1就是要被我们直接加到结果里面而不需要进行乘法运算的了。用一个sum变量存一下，把1加进去。第二个数字是1，后面的运算符号是*，那1就要和乘号后面的数相乘。得到一个数，后面是＋号，那把前面的乘积累计到sum，最后是4，也直接加上去。</p><p>在这个模拟过程中，我们不难发现，其实我们只需要关注两个东西。一个是当前的总和，一个是需要乘了之后才能加上去的和。那么乘积我们用t来维护，遇到乘号时，累积到当前结果t,如果是加号，说明乘法段结束，把t加入总和sum，然后重置t。最终sum+t的答案就是最终结果</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> mod = <span class="number">10000</span>;</span><br><span class="line"><span class="type">long</span> <span class="type">long</span> x,s,t; <span class="comment">//x是当前的数，s是和，t是当前段的乘积</span></span><br><span class="line"><span class="type">char</span> c;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">    cin&gt;&gt;t;<span class="comment">//先读入第一个数，之后每次读入一个符号一个数</span></span><br><span class="line">    <span class="keyword">while</span>(cin &gt;&gt;c &amp;&amp; c != <span class="string">&#x27;\n&#x27;</span>)&#123; <span class="comment">//最后会读到换行符</span></span><br><span class="line">        cin &gt;&gt;x;</span><br><span class="line">        <span class="keyword">if</span>(c == <span class="string">&#x27;*&#x27;</span>) t = t * x % mod; <span class="comment">//是乘号就相乘</span></span><br><span class="line">        <span class="keyword">else</span> s = (s + t) % mod,t = x; <span class="comment">//加号就加上上一段的积，t变为下一段的第一个数</span></span><br><span class="line">    &#125;</span><br><span class="line">   cout &lt;&lt;(s + t) % mod;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></div></figure><p>其实到这里，就非常接近栈的思想了。都是用完即丢，一边接受一边计算一边处理。</p><p>采取同样的输入方式，如果是×号，获取栈顶的元素，然后和当下数字相乘，然后把栈顶元素弹出来，把乘后的数字放上去。如果碰到的是加号，不需要处理，后面把栈里面的元素都一起加起来就好。（因为乘法运算算完都是加法运算了）。</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> mod = <span class="number">10000</span>;</span><br><span class="line"><span class="type">char</span> op;</span><br><span class="line">stack&lt;<span class="type">int</span>&gt;q;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="type">int</span> t,m;</span><br><span class="line">    cin &gt;&gt;t;</span><br><span class="line">    q.<span class="built_in">push</span>(t);</span><br><span class="line">    <span class="keyword">while</span>(cin&gt;&gt;op &amp;&amp; op!=<span class="string">&#x27;\n&#x27;</span>) &#123;</span><br><span class="line">        <span class="type">int</span> num;</span><br><span class="line">        cin &gt;&gt;num;</span><br><span class="line">        <span class="keyword">if</span>(op==<span class="string">&#x27;*&#x27;</span>) &#123;</span><br><span class="line">            <span class="type">int</span> top=q.<span class="built_in">top</span>();</span><br><span class="line">            q.<span class="built_in">pop</span>();</span><br><span class="line">            q.<span class="built_in">push</span>(num*top%mod);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">else</span> &#123;</span><br><span class="line">            q.<span class="built_in">push</span>(num%mod);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="type">int</span> sum=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span>(!q.<span class="built_in">empty</span>()) &#123;</span><br><span class="line">        sum=(sum+q.<span class="built_in">top</span>())%mod;</span><br><span class="line">        q.<span class="built_in">pop</span>();</span><br><span class="line">    &#125;</span><br><span class="line">    cout &lt;&lt;sum&lt;&lt;endl;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></div></figure><p>用熟练了之后你会发现其实用的挺顺手的。也许你会说，这还不如前面的动态维护呢，时间复杂度都是O(n)。</p><p>栈的空间复杂度还可能大一点。但是动态维护的方法仅适用于+，*。栈的话可以扩展到有括号的。这时候你就能理会栈的方便了。（后面会继续讲解单调栈以及进阶版表达式求值和括号匹配例题）</p>        <h2 id="队列实战1（用队列实现bfs）"   >          <a href="#队列实战1（用队列实现bfs）" class="heading-link"><i class="fas fa-link"></i></a><a href="#队列实战1（用队列实现bfs）" class="headerlink" title="队列实战1（用队列实现bfs）"></a>队列实战1（用队列实现bfs）</h2>      <p><strong>Breadth First Search (BFS) 宽度优先搜索</strong>，又称广度优先搜索，是图搜索算法中的一种，BFS 顾名思义，我们搜索的过程是平铺开进行搜索，即从起点开始，将所有和它<strong>相邻的结点</strong>都搜索一遍，然后再一个个去搜索这些相邻结点自己的相邻节点，<strong>一层一层铺开</strong>，从而进行搜索。其搜索过程就像水中的涟漪，从中心开始，<strong>向四周进行扩散</strong>，直到遍历完整个图。（贴心的备上视频）</p><p><video src="../images/%E9%98%9F%E5%88%97.mp4"></video></p><p>对于 BFS 算法，正如上面所说的，我们需要一层一层遍历所有的相邻结点。那么<strong>相邻结点之间的先后顺序</strong>如何确定？因此我们需要一个数据结构来进行存储和操作，需要使得<strong>先遍历的结点先被存储</strong>，直到当前层都被存储后，按照先后顺序，<strong>先被存储</strong>的结点也会被<strong>先取出来</strong>，继续遍历它的相邻结点。</p><p>我们可以惊奇的发现，这个需求不就是我们的<strong>队列</strong>吗，<em><strong>First In First Out (FIFO)*</strong> 完全契合这里的 use case。因此对于 BFS 我们需要使用 Queue 这样的一个数据结构，来</em><em>存储每一层的结点</em>*，同时**维护『先进先出 FIFO』**的顺序。</p><p>理论知识差不多就这样了。文字描述有点抽象，附上代码讲解</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++,h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std; </span><br><span class="line"></span><br><span class="line"><span class="comment">// 定义二叉树节点结构</span></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">TreeNode</span> &#123;</span><br><span class="line">    <span class="type">int</span> val;           <span class="comment">// 节点存储的值</span></span><br><span class="line">    TreeNode* left;    <span class="comment">// 指向左子节点的指针</span></span><br><span class="line">    TreeNode* right;   <span class="comment">// 指向右子节点的指针</span></span><br><span class="line">    <span class="comment">// 构造函数：初始化节点值，左右子节点默认为空（NULL）</span></span><br><span class="line">    <span class="built_in">TreeNode</span>(<span class="type">int</span> x) : <span class="built_in">val</span>(x), <span class="built_in">left</span>(<span class="literal">NULL</span>), <span class="built_in">right</span>(<span class="literal">NULL</span>) &#123;&#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 二叉树的层序遍历（BFS 实现）</span></span><br><span class="line"><span class="comment"> * @param root 二叉树的根节点指针</span></span><br><span class="line"><span class="comment"> * @return 二维数组，每一层节点的值组成一个子数组</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">vector&lt;vector&lt;<span class="type">int</span>&gt;&gt; <span class="built_in">levelOrder</span>(TreeNode* root) &#123;</span><br><span class="line">    vector&lt;vector&lt;<span class="type">int</span>&gt;&gt; ans;  <span class="comment">// 存储最终结果的二维数组</span></span><br><span class="line">    <span class="keyword">if</span> (root == <span class="literal">NULL</span>) <span class="keyword">return</span> ans;  <span class="comment">// 空树直接返回</span></span><br><span class="line">    </span><br><span class="line">    queue&lt;TreeNode*&gt; q;       <span class="comment">// 使用队列辅助 BFS 遍历</span></span><br><span class="line">    q.<span class="built_in">push</span>(root);             <span class="comment">// 根节点入队</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">while</span> (!q.<span class="built_in">empty</span>()) &#123;      <span class="comment">// 队列不空时循环</span></span><br><span class="line">        <span class="type">int</span> s = q.<span class="built_in">size</span>();     <span class="comment">// 当前层的节点数</span></span><br><span class="line">        vector&lt;<span class="type">int</span>&gt; v;        <span class="comment">// 存储当前层的节点值</span></span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 遍历当前层的所有节点</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; s; i++) &#123;</span><br><span class="line">            TreeNode* node = q.<span class="built_in">front</span>();  <span class="comment">// 取出队首节点</span></span><br><span class="line">            q.<span class="built_in">pop</span>();                     <span class="comment">// 弹出队首节点</span></span><br><span class="line">            </span><br><span class="line">            <span class="comment">// 将当前节点的左子节点加入队列（下一层）</span></span><br><span class="line">            <span class="keyword">if</span> (node-&gt;left != <span class="literal">NULL</span>) q.<span class="built_in">push</span>(node-&gt;left);</span><br><span class="line">            <span class="comment">// 将当前节点的右子节点加入队列（下一层）</span></span><br><span class="line">            <span class="keyword">if</span> (node-&gt;right != <span class="literal">NULL</span>) q.<span class="built_in">push</span>(node-&gt;right);</span><br><span class="line">            </span><br><span class="line">            v.<span class="built_in">push_back</span>(node-&gt;val);  <span class="comment">// 记录当前节点的值</span></span><br><span class="line">        &#125;</span><br><span class="line">        ans.<span class="built_in">push_back</span>(v);  <span class="comment">// 将当前层的结果加入最终答案</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> ans;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 1. 构建一棵二叉树（示例）</span></span><br><span class="line">    <span class="comment">//       3</span></span><br><span class="line">    <span class="comment">//      / \</span></span><br><span class="line"><span class="comment">    //     9  20</span></span><br><span class="line">    <span class="comment">//       /  \</span></span><br><span class="line"><span class="comment">    //      15   7</span></span><br><span class="line">    TreeNode* root = <span class="keyword">new</span> <span class="built_in">TreeNode</span>(<span class="number">3</span>);          <span class="comment">// 根节点</span></span><br><span class="line">    root-&gt;left = <span class="keyword">new</span> <span class="built_in">TreeNode</span>(<span class="number">9</span>);              <span class="comment">// 左子节点</span></span><br><span class="line">    root-&gt;right = <span class="keyword">new</span> <span class="built_in">TreeNode</span>(<span class="number">20</span>);            <span class="comment">// 右子节点</span></span><br><span class="line">    root-&gt;right-&gt;left = <span class="keyword">new</span> <span class="built_in">TreeNode</span>(<span class="number">15</span>);     <span class="comment">// 右左孙子节点</span></span><br><span class="line">    root-&gt;right-&gt;right = <span class="keyword">new</span> <span class="built_in">TreeNode</span>(<span class="number">7</span>);     <span class="comment">// 右右孙子节点</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">// 2. 调用层序遍历函数</span></span><br><span class="line">    vector&lt;vector&lt;<span class="type">int</span>&gt;&gt; result = <span class="built_in">levelOrder</span>(root);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 3. 打印结果</span></span><br><span class="line">    cout &lt;&lt; <span class="string">&quot;层序遍历结果：&quot;</span> &lt;&lt; endl;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">auto</span>&amp; level : result) &#123;       <span class="comment">// 遍历每一层</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> val : level) &#123;        <span class="comment">// 遍历当前层的每个值</span></span><br><span class="line">            cout &lt;&lt; val &lt;&lt; <span class="string">&quot; &quot;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        cout &lt;&lt; endl;  <span class="comment">// 每层换行</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 4. 释放内存（实际工程中需要，此处简化）</span></span><br><span class="line">    <span class="comment">// delete root-&gt;right-&gt;right;</span></span><br><span class="line">    <span class="comment">// delete root-&gt;right-&gt;left;</span></span><br><span class="line">    <span class="comment">// delete root-&gt;right;</span></span><br><span class="line">    <span class="comment">// delete root-&gt;left;</span></span><br><span class="line">    <span class="comment">// delete root;</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;  <span class="comment">// 程序正常结束</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>看不懂没有关系~~，你只需要大概有个概念就好。以后慢慢就自己懂了（疑似自己讲不清楚开始画饼）。</p><p>其实主要原因是这只是个入门系列，不宜讲得太深。因为队列只是一个工具，它往往要结合别的算法，比如bfs，所以后面会开一期bfs专栏来继续队列这一系列。</p><p>后面我们会讲到，栈与队列如何实现对方，单调栈，单调队列，优先队列，滑动窗口（小小预告画饼）</p>]]></content>
      
      
      <categories>
          
          <category> 算法 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> 算法 </tag>
            
            <tag> acm </tag>
            
            <tag> 数据结构 </tag>
            
            <tag> 栈与队列 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>线性表（包含链表）</title>
      <link href="/2025/09/24/%E7%BA%BF%E6%80%A7%E8%A1%A8(%E5%8C%85%E5%90%AB%E9%93%BE%E8%A1%A8)/"/>
      <url>/2025/09/24/%E7%BA%BF%E6%80%A7%E8%A1%A8(%E5%8C%85%E5%90%AB%E9%93%BE%E8%A1%A8)/</url>
      
        <content type="html"><![CDATA[<p>要了解线性表，首先要了解线性结构</p>        <h1 id="线性结构的特点"   >          <a href="#线性结构的特点" class="heading-link"><i class="fas fa-link"></i></a><a href="#线性结构的特点" class="headerlink" title="线性结构的特点"></a>线性结构的特点</h1>      <ul><li>只有一个首节点和尾结点</li><li>除首尾节点外，其他节点只有一个直接前驱和直接后继</li></ul><p>简而言之，线性结构反映结构的逻辑关系是<strong>一对一</strong>的</p><p>线性结构包含线性表，堆栈，队列，字符串，数组。其中最常用的是线性表。</p>        <h1 id="线性表的定义"   >          <a href="#线性表的定义" class="heading-link"><i class="fas fa-link"></i></a><a href="#线性表的定义" class="headerlink" title="线性表的定义"></a>线性表的定义</h1>      <p>用数据元素的有限序列表示</p><p><img src="D:/blog/artemis/source/images/image-20251111103800214.png" alt="image-20251111103800214"></p><p>二十六个英文字母组成的英文表，元素间关系是线性</p><p><strong>同一线性表中的元素必定有相同特性</strong></p><p>线性表中的数据类型可以是简单类型也可以是复杂类型</p>        <h1 id="线性表的顺序表示"   >          <a href="#线性表的顺序表示" class="heading-link"><i class="fas fa-link"></i></a><a href="#线性表的顺序表示" class="headerlink" title="线性表的顺序表示"></a>线性表的顺序表示</h1>      <p>线性表的顺序表示可以称为<strong>顺序存储结构</strong>或<strong>顺序映像</strong></p><p><strong>顺序存储</strong>：把<strong>逻辑上相邻</strong>的数据元素存储在<strong>物理上相邻</strong>的存储单元中的存储结构。</p><p><strong>顺序存储方法</strong>：用<strong>一组地址连续</strong>的存储单元存储。可通过<strong>数组</strong>实现</p>        <h1 id="线性表的重要基本操作"   >          <a href="#线性表的重要基本操作" class="heading-link"><i class="fas fa-link"></i></a><a href="#线性表的重要基本操作" class="headerlink" title="线性表的重要基本操作"></a>线性表的重要基本操作</h1>      <blockquote><p>[!NOTE]</p><p>若函数括号内为（SqList &amp;L）表示引用传递，可能会修改参数。若是（SqList L，则表示值传递，不能修改原数据）</p></blockquote>        <h2 id="定义"   >          <a href="#定义" class="heading-link"><i class="fas fa-link"></i></a><a href="#定义" class="headerlink" title="定义"></a>定义</h2>      <p>结构体中定义地址和长度</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">define</span> MAXSIZE 100</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">struct</span>&#123;</span><br><span class="line">    ElemType *elem; <span class="comment">//地址</span></span><br><span class="line">    <span class="type">int</span> length;<span class="comment">//线性表长度</span></span><br><span class="line">&#125;sqList;</span><br></pre></td></tr></table></div></figure>        <h2 id="初始化（两种方法，引用与指针）"   >          <a href="#初始化（两种方法，引用与指针）" class="heading-link"><i class="fas fa-link"></i></a><a href="#初始化（两种方法，引用与指针）" class="headerlink" title="初始化（两种方法，引用与指针）"></a>初始化（两种方法，引用与指针）</h2>      <p><strong>用new分配空间，再设置长度为0（空表长度为0）</strong></p>        <h3 id="引用"   >          <a href="#引用" class="heading-link"><i class="fas fa-link"></i></a><a href="#引用" class="headerlink" title="引用"></a>引用</h3>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">status <span class="title">InitList_Sq</span><span class="params">(SqList &amp;L)</span></span>&#123;<span class="comment">//构造一个空的顺序表</span></span><br><span class="line">    L.elem=<span class="keyword">new</span> ElemType[MAXSIZE];<span class="comment">//分配空间</span></span><br><span class="line">    <span class="keyword">if</span>(!L.elem) <span class="built_in">exit</span>(OVERFLOW);<span class="comment">//OVERFLOW前文定义为-1，此句表示分配失败</span></span><br><span class="line">    L.length=<span class="number">0</span>;<span class="comment">//空表长度为0</span></span><br><span class="line">    <span class="keyword">return</span> OK;<span class="comment">//前文define OK 1</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h3 id="指针"   >          <a href="#指针" class="heading-link"><i class="fas fa-link"></i></a><a href="#指针" class="headerlink" title="指针"></a>指针</h3>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">status <span class="title">InitList_Sq</span><span class="params">(SqList &amp;L)</span></span>&#123;</span><br><span class="line">    L-&gt;elem=<span class="keyword">new</span> ElemType[MAXSIZE];</span><br><span class="line">    <span class="keyword">if</span>(!L-&gt;elem) <span class="built_in">exit</span>(OVERFLOW);</span><br><span class="line">    L-&gt;length=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">return</span> OK;<span class="comment">//前文define OK 1</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="销毁线性表"   >          <a href="#销毁线性表" class="heading-link"><i class="fas fa-link"></i></a><a href="#销毁线性表" class="headerlink" title="销毁线性表"></a>销毁线性表</h2>      <p>用delete删除线性表</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">DestroyList</span><span class="params">(SqList &amp;L)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(L.elem) <span class="keyword">delete</span>[]L.elem;<span class="comment">//释放存储空间</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="清空线性表"   >          <a href="#清空线性表" class="heading-link"><i class="fas fa-link"></i></a><a href="#清空线性表" class="headerlink" title="清空线性表"></a>清空线性表</h2>      <p>清空线性表只需把长度置0即可</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">ClearList</span><span class="params">(SqList &amp;L)</span></span>&#123;</span><br><span class="line">    L.length=<span class="number">0</span>;<span class="comment">//线性表长度置为0</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="求线性表长度"   >          <a href="#求线性表长度" class="heading-link"><i class="fas fa-link"></i></a><a href="#求线性表长度" class="headerlink" title="求线性表长度"></a>求线性表长度</h2>      <p>L.length</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">GetLength</span><span class="params">(SqList L)</span></span>&#123;</span><br><span class="line">    <span class="keyword">return</span> (L.length);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="判断是否为空"   >          <a href="#判断是否为空" class="heading-link"><i class="fas fa-link"></i></a><a href="#判断是否为空" class="headerlink" title="判断是否为空"></a>判断是否为空</h2>      <p>长度为0则返回1 表示空了</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">IsEmpty</span><span class="params">(SqList L)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(L.length==<span class="number">0</span>)<span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="取值（获取第i个数据）"   >          <a href="#取值（获取第i个数据）" class="heading-link"><i class="fas fa-link"></i></a><a href="#取值（获取第i个数据）" class="headerlink" title="取值（获取第i个数据）"></a>取值（获取第i个数据）</h2>      <p>线性表通过下标直接定位元素</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">GetElem</span><span class="params">(SqList L,<span class="type">int</span> i,ElemType &amp;e)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(i&lt;<span class="number">1</span> || i&gt;L.length) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="comment">//判断i值是否合理</span></span><br><span class="line">    e=L.elem[i<span class="number">-1</span>];</span><br><span class="line">    <span class="comment">//第i-1的单元里存着第i个数控</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="查找（找值为e的数据元素）"   >          <a href="#查找（找值为e的数据元素）" class="heading-link"><i class="fas fa-link"></i></a><a href="#查找（找值为e的数据元素）" class="headerlink" title="查找（找值为e的数据元素）"></a>查找（找值为e的数据元素）</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">LocateELem</span><span class="params">(SqList L,ElemType e)</span></span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">0</span>;i&lt;L.length;i++)&#123;</span><br><span class="line">        <span class="keyword">if</span>(L.elem[i]==e)&#123;</span><br><span class="line">            <span class="keyword">return</span> i<span class="number">+1</span>;<span class="comment">//数组通常从0开始计数，但是用户习惯凑从1开始，这是告诉你，你要找的元素是第i+1个，下标是i</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="插入（第i个前插入e）"   >          <a href="#插入（第i个前插入e）" class="heading-link"><i class="fas fa-link"></i></a><a href="#插入（第i个前插入e）" class="headerlink" title="插入（第i个前插入e）"></a>插入（第i个前插入e）</h2>      <p>步骤</p><ul><li>判断插入位置是否合法</li><li>判断存储空间是否已满</li><li>将n至i的元素依次向后移动一位空出i位置</li><li>将要插入的e放入第i个位置</li><li>表长加一，插入成功返回ok</li></ul><p>注意，第i个前插入e，则e下标为i-1</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">status <span class="title">ListInsert_Sq</span><span class="params">(SqList &amp;L,<span class="type">int</span> i,ElemType e)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(i&lt;<span class="number">1</span> || i&gt;L.length<span class="number">+1</span>)<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">if</span>(L.length==MAXSIZE)<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> j=L.length<span class="number">-1</span>;j&gt;=i<span class="number">-1</span>;j--)&#123;<span class="comment">//从最后一个元素开始遍历到i-1，依次后移则下标都增加1</span></span><br><span class="line">        L.elem[j<span class="number">+1</span>]=L.elem[j];</span><br><span class="line">    &#125;</span><br><span class="line">        L.elem[i<span class="number">-1</span>]=e;<span class="comment">//插入e</span></span><br><span class="line">    ++L.length;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><blockquote><p>[!NOTE]</p><p>各种位置插入（n+1个可能）的平均移动次数为<strong>n&#x2F;2</strong></p></blockquote>        <h2 id="删除（第i个）"   >          <a href="#删除（第i个）" class="heading-link"><i class="fas fa-link"></i></a><a href="#删除（第i个）" class="headerlink" title="删除（第i个）"></a>删除（第i个）</h2>      <p>步骤</p><ul><li>判断i是否合法</li><li>将欲删除的元素保留在e中</li><li>将第i+1至n位元素向前移动一个位置</li><li>表长减一，删除成功返回ok</li></ul><blockquote><p>[!CAUTION]</p><p>这里判断合法,i不能超过length，但是插入时是不能超过i+1</p></blockquote><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">status <span class="title">ListDelete_Sq</span><span class="params">(SqList &amp;L.<span class="type">int</span> i)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>((i&lt;<span class="number">1</span>) || (i&gt;L.length)) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> j=i;i&lt;L.length;j++)&#123;</span><br><span class="line">        L.elem[j<span class="number">-1</span>]=L.elem[j];</span><br><span class="line">    &#125;</span><br><span class="line">    --L.length;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p><strong>若要考虑在各种位置删除（共n种可能）的平均移动次数，该如何计算？</strong></p><p><img src="D:/blog/artemis/source/images/image-20251111144834143.png" alt="image-20251111144834143"></p>        <h1 id="顺序存储结构特点"   >          <a href="#顺序存储结构特点" class="heading-link"><i class="fas fa-link"></i></a><a href="#顺序存储结构特点" class="headerlink" title="顺序存储结构特点"></a>顺序存储结构特点</h1>      <p>查找插入删除的平均时间为 <strong>O(n)</strong></p><p>空间复杂度为O（1）</p><img src="D:/blog/artemis/source/images/image-20251111145051818.png" alt="image-20251111145051818" style="zoom: 33%;" /><img src="D:/blog/artemis/source/images/image-20251111145112605.png" alt="image-20251111145112605" style="zoom:33%;" />        <h1 id="什么是链表？"   >          <a href="#什么是链表？" class="heading-link"><i class="fas fa-link"></i></a><a href="#什么是链表？" class="headerlink" title="什么是链表？"></a>什么是链表？</h1>      <p>链表是一种用于<strong>存储数据</strong>的数据结构，通过<strong>像链条一般的指针</strong>连接元素（得名原因）。它是<strong>线性表</strong>的链式存储映像，称为<strong>线性表的链式存储结构</strong></p><p>它的显著优势是<strong>删除和插入数据</strong>十分方便（数组要O(n)，链表只需O(1)），但<strong>寻找和读取数据表现欠佳</strong>（数组只需O(1)，链表需要O(n)）。</p>        <h1 id="链表的组成分类"   >          <a href="#链表的组成分类" class="heading-link"><i class="fas fa-link"></i></a><a href="#链表的组成分类" class="headerlink" title="链表的组成分类"></a>链表的组成分类</h1>      <p>链表由一系列节点（node）组成，每个节点（同结点）有两个部分：</p><ul><li><strong>数据域</strong>：存储实际数据，(如int value）</li><li><strong>指针域</strong>： 存储下一个节点的地址（如 node *next）</li></ul><p>链表分为，单链表，双链表，循环链表。</p>        <h2 id="单链表"   >          <a href="#单链表" class="heading-link"><i class="fas fa-link"></i></a><a href="#单链表" class="headerlink" title="单链表"></a>单链表</h2>      <p><strong>结点只有一个指针域</strong>，称为单链表或者线性链表。<strong>由表头唯一确定，所以可以用头指针的名字来命名</strong>。若头指针是L,则链表命名为L</p><p><img src="/../../../blog/artemis/source/images/image-20260106151754807.png" alt="image-20260106151754807"></p><p>注意：后文列举代码默认已定义Node结构体</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="keyword">struct</span> <span class="title class_">LNode</span>&#123;</span><br><span class="line">    ElemType data;</span><br><span class="line">    <span class="keyword">struct</span> <span class="title class_">LNode</span> *next;</span><br><span class="line">&#125;LNode,*LinkList</span><br><span class="line">    <span class="comment">//*LinkList 为 LNode类型的指针</span></span><br><span class="line">    <span class="comment">//LNode *p=LinkList p  两种写法都可以</span></span><br></pre></td></tr></table></div></figure>        <h2 id="双向链表-应该不考，学有余力可看"   >          <a href="#双向链表-应该不考，学有余力可看" class="heading-link"><i class="fas fa-link"></i></a><a href="#双向链表-应该不考，学有余力可看" class="headerlink" title="双向链表(应该不考，学有余力可看)"></a>双向链表(应该不考，学有余力可看)</h2>      <p>有两个指针域(有左右之分)的链表，称为双链表</p><p><img src="/../../../blog/artemis/source/images/image-20260106151806982.png" alt="image-20260106151806982"></p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="keyword">struct</span> <span class="title class_">DuLNode</span>&#123;</span><br><span class="line">    ElemType data;</span><br><span class="line">    <span class="keyword">struct</span> <span class="title class_">DuLNode</span> *prior;</span><br><span class="line">    <span class="keyword">struct</span> <span class="title class_">DuLNode</span> *next;</span><br><span class="line">&#125;DuLNode,*DuLinkList</span><br></pre></td></tr></table></div></figure>        <h2 id="循环链表（也应该不考）"   >          <a href="#循环链表（也应该不考）" class="heading-link"><i class="fas fa-link"></i></a><a href="#循环链表（也应该不考）" class="headerlink" title="循环链表（也应该不考）"></a>循环链表（也应该不考）</h2>      <p>首尾相接的链表是循环列表。（尾节点的 <code>next</code> 指向<strong>头节点</strong>）由于这个特性，在插入数据时需要判断链表是否为空，为空则自身循环，不空则正常插入数据。（从循环链表中的任何一个节点都可以找到其他任何节点，而单链表不行）</p><p><img src="/../../../blog/artemis/source/images/image-20260106151826150.png" alt="image-20260106151826150"></p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">insertNode</span><span class="params">(<span class="type">int</span> i, Node *p)</span> </span>&#123;</span><br><span class="line">  Node *node = <span class="keyword">new</span> Node;<span class="comment">//创建新节点</span></span><br><span class="line">  node-&gt;value = i;<span class="comment">//设置节点值</span></span><br><span class="line">  node-&gt;next = <span class="literal">NULL</span>;<span class="comment">//初始化next指针</span></span><br><span class="line">  <span class="keyword">if</span> (p == <span class="literal">NULL</span>) &#123;<span class="comment">//链表为空</span></span><br><span class="line">    p = node;<span class="comment">//p指向新节点</span></span><br><span class="line">    node-&gt;next = node;<span class="comment">//自己指向自己</span></span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    node-&gt;next = p-&gt;next;<span class="comment">//新节点指向p的后继</span></span><br><span class="line">    p-&gt;next = node;<span class="comment">//p指向新节点</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="链表常见运算符和关键字"   >          <a href="#链表常见运算符和关键字" class="heading-link"><i class="fas fa-link"></i></a><a href="#链表常见运算符和关键字" class="headerlink" title="链表常见运算符和关键字"></a>链表常见运算符和关键字</h2>      <p>初见代码你也许疑惑，new是什么？</p><p><strong>它是c++中的关键字，用于动态分配内存。</strong></p><p>例如</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> *p=<span class="keyword">new</span> <span class="type">int</span> <span class="comment">//分配一个int 大小的内存</span></span><br><span class="line"><span class="type">int</span> *p=<span class="keyword">new</span> <span class="built_in">int</span> (<span class="number">100</span>)<span class="comment">//初始值为100</span></span><br></pre></td></tr></table></div></figure><p><code>-&gt;</code>则是c&#x2F;c++中的箭头运算符，等价于，先解引用指针，然后访问成员。</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">Node* node=<span class="keyword">new</span> Node;</span><br><span class="line">    node-&gt;value=<span class="number">5</span>;<span class="comment">//设置节点的value为5，等价于（*node）.value=5</span></span><br><span class="line">    node-&gt;next=<span class="literal">NULL</span>;<span class="comment">//设置Next指针为NULL，等价于 (*node).next=NULL</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="链表的一些概念"   >          <a href="#链表的一些概念" class="heading-link"><i class="fas fa-link"></i></a><a href="#链表的一些概念" class="headerlink" title="链表的一些概念"></a>链表的一些概念</h2>      <p>我们还提到了头结点的概念，其实与之对应的还有尾结点，头指针，首元结点。</p><ul><li><strong>头指针</strong>：指向链表中第一个元素的指针</li><li><strong>头结点</strong>：是在链表的<strong>首元结点之前附设</strong>的一个结点，**数据域内可以为空，**只存放表长和空表标志等信息。<strong>但此结点不能计入链表长度值</strong></li><li><strong>首元结点</strong>：链表中存储第一个数据元素a1的结点</li></ul><p><strong>按有无头结点划分</strong></p><img src="../../../blog/artemis/source/images/image-20260106151840434.png" alt="image-20260106151840434" style="zoom:50%;" /><p>有头结点时，当当头结点的指针域为空时表示空表。</p>        <h3 id="为什么要设置头结点？"   >          <a href="#为什么要设置头结点？" class="heading-link"><i class="fas fa-link"></i></a><a href="#为什么要设置头结点？" class="headerlink" title="为什么要设置头结点？"></a>为什么要设置头结点？</h3>      <ul><li><p><strong>便于首元结点的处理。</strong></p><p>**首元结点的地址保存在头结点的指针域中，**所以在链表的第一个位置上的操作和其他位置一致，无需进行特殊处理。</p></li><li><p>便于<strong>空表和非空表的统一</strong></p><p>无论链表是否为空，<strong>头指针都是指向头结点的非空指针</strong>。</p></li></ul>        <h3 id="链表的特点"   >          <a href="#链表的特点" class="heading-link"><i class="fas fa-link"></i></a><a href="#链表的特点" class="headerlink" title="链表的特点"></a>链表的特点</h3>      <ul><li><p>结点在<strong>存储器中的位置是任意</strong>的，逻辑相邻的数据元素在物理上不一定相邻</p></li><li><p>访问时<strong>只能通过头指针进入链表</strong>，所以寻找第一个结点和最后一个结点的所需时间不等。</p></li></ul><p><strong>这种存取元素的方法称为<u>顺序存取法</u></strong></p>        <h1 id="单向链表的操作（重点，老师说了要考，可能要写代码当大题）"   >          <a href="#单向链表的操作（重点，老师说了要考，可能要写代码当大题）" class="heading-link"><i class="fas fa-link"></i></a><a href="#单向链表的操作（重点，老师说了要考，可能要写代码当大题）" class="headerlink" title="单向链表的操作（重点，老师说了要考，可能要写代码当大题）"></a>单向链表的操作（重点，老师说了要考，可能要写代码当大题）</h1>      <ol><li>初始化 2.  取值 3.  查找 4.  插入 5.  删除</li></ol>        <h2 id="链表运算时间"   >          <a href="#链表运算时间" class="heading-link"><i class="fas fa-link"></i></a><a href="#链表运算时间" class="headerlink" title="链表运算时间"></a>链表运算时间</h2>      <p>查找：因<strong>线性链表只能顺序存取</strong>，所有查找时要从头指针找起，O(n)</p><p>插入删除：不需要移动元素，只需要修改指针，只需O(1).  <strong>但是，如果要在单链表中进行前插或删除操作，由于要从头查找前驱结点，所耗时间复杂度为</strong> <strong>O(n)</strong> 。</p>        <h2 id="初始化"   >          <a href="#初始化" class="heading-link"><i class="fas fa-link"></i></a><a href="#初始化" class="headerlink" title="初始化"></a>初始化</h2>      <ul><li>new分配一个内存</li><li>头结点的指针域置空</li></ul><p>注意，后文列举代码默认有此环境</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">ifndef</span> DULINKEDLIST_H</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> DULINKEDLIST_H</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 状态码定义</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> TRUE 1</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> FALSE 0</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> OK 1</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ERROR 0</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> INFEASIBLE -1</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> OVERFLOW -2</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 状态类型定义</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="type">int</span> Status;</span><br><span class="line"><span class="keyword">typedef</span> <span class="type">int</span> ElemType; <span class="comment">// 可根据需要修改元素类型</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">struct</span> <span class="title class_">LNode</span>&#123;</span><br><span class="line">    <span class="type">int</span> data;</span><br><span class="line">    <span class="keyword">struct</span> <span class="title class_">LNode</span> *next;</span><br><span class="line">&#125;LNode,*LinkList<span class="comment">//*LinkList为Lnode类型的指针</span></span><br><span class="line">    <span class="comment">//指针变量p表示结点地址</span></span><br><span class="line">    <span class="comment">//结点变量*p表示一个结点</span></span><br><span class="line">    <span class="comment">//注意：struct LNode结构体类型有了一个别名 LNode。</span></span><br><span class="line">    <span class="comment">//struct LNode *指针类型有了一个别名 LinkList。</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">//初始化构造一个空表</span></span><br><span class="line">    <span class="comment">//生成新结点作头结点，用头指针L指向头结点，头结点的指针域置空</span></span><br><span class="line">    <span class="function">Status <span class="title">InitList_L</span><span class="params">(LinkList &amp;L)</span></span>&#123;</span><br><span class="line">    L=<span class="keyword">new</span> LNode;</span><br><span class="line">    L-&gt;next=<span class="literal">NULL</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="取值（第i个元素赋值为e）"   >          <a href="#取值（第i个元素赋值为e）" class="heading-link"><i class="fas fa-link"></i></a><a href="#取值（第i个元素赋值为e）" class="headerlink" title="取值（第i个元素赋值为e）"></a>取值（第i个元素赋值为e）</h2>      <ul><li>创建指针变量p用来访问节点内容</li><li>创建计数器j&#x3D;1用来记录遍历到第几个元素了</li><li>遍历直到第i个节点，p要非空</li><li>判断位置合不合法（p是不是空的,i的值是否合理）</li><li>e-&gt;data赋值为e</li><li>返回1</li></ul><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//获取链表中第i个元素的值</span></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">GetElem</span><span class="params">(LinkList L,<span class="type">int</span> i,ElemType &amp;e)</span></span>&#123;</span><br><span class="line">    LNode *p=L-&gt;next; <span class="comment">//p指向第一个结点（跳过头结点） 等价于LinkList p=L-&gt;next</span></span><br><span class="line">    <span class="type">int</span> j=<span class="number">1</span>;<span class="comment">//计数器</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">//遍历链表直到第i个节点或链表结束，p不为NULL时继续循环</span></span><br><span class="line">    <span class="keyword">while</span>(p &amp;&amp; j&lt;i)&#123;</span><br><span class="line">        p=p-&gt;next;</span><br><span class="line">        j++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//循环跑完之后j=i</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">//p空或j&gt;i说明没有找到，i位置不合法，返回0</span></span><br><span class="line">    <span class="keyword">if</span>(!p || j&gt;i)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125; </span><br><span class="line">    </span><br><span class="line">    e=p-&gt;data;<span class="comment">//通过指针参数返回元素值</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">使用示例</span><br><span class="line">LinkList list;<span class="comment">//初始化的链表</span></span><br><span class="line"><span class="type">int</span> value;</span><br><span class="line"><span class="keyword">if</span>(<span class="built_in">GetElem</span>(list,<span class="number">3</span>,&amp;value)==<span class="number">1</span>)&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;第三个元素是：%d\n&quot;</span>,value);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">else</span>&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;第三个元素不存在\n&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="销毁"   >          <a href="#销毁" class="heading-link"><i class="fas fa-link"></i></a><a href="#销毁" class="headerlink" title="销毁"></a>销毁</h2>      <ul><li><p>创造一个指针变量p临时保存要删除的节点</p></li><li><p>遍历链表所有节点（while(L)），p指向当前节点，L移向下一个节点</p></li><li><p>删除p指向的节点</p><p>直接 <code>delete L</code>后，<code>L-&gt;next</code>无法再访问（因为 <code>L</code>指向的内存已释放），导致后续节点丢失。</p></li></ul><figure class="highlight c++"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">Destroy</span><span class="params">(LinkList &amp;L)</span></span>&#123;</span><br><span class="line">    LinkList p;<span class="comment">//用于临时保存要删除的节点</span></span><br><span class="line">    <span class="keyword">while</span>(L)&#123;<span class="comment">//当链表还有节点时继续循环</span></span><br><span class="line">        p=L;<span class="comment">//P指向当前要删除的节点</span></span><br><span class="line">        L=L-&gt;next;<span class="comment">//L移向下一个节点</span></span><br><span class="line">        <span class="keyword">delete</span> p;<span class="comment">//删除p指向的节点</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> OK;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="清空"   >          <a href="#清空" class="heading-link"><i class="fas fa-link"></i></a><a href="#清空" class="headerlink" title="清空"></a>清空</h2>      <ul><li>同销毁，但是地址要保留，所以需要再开一个遍历q保存下一个节点的地址</li><li>创建两个指针变量pq</li><li>p指向第一个节点，while(p)开始遍历，把下一个节点的地址保存在q里面</li><li>删除p，让q&#x3D;p，继续删除</li><li>删除完后，头结点指针域为空</li></ul><figure class="highlight c++"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">Clear</span><span class="params">(LinkList &amp;L)</span></span>&#123;</span><br><span class="line">    LinkList p,q;</span><br><span class="line">    p=L-&gt;next;<span class="comment">//p指向第一个节点</span></span><br><span class="line">    <span class="keyword">while</span>(p)&#123;<span class="comment">//没到末尾</span></span><br><span class="line">        q=p-&gt;next;<span class="comment">//先保存下一个节点的地址，防止删除后丢失链表</span></span><br><span class="line">        <span class="keyword">delete</span> p;</span><br><span class="line">        p=q;</span><br><span class="line">    &#125;</span><br><span class="line">    L-&gt;next=<span class="literal">NULL</span>;<span class="comment">//头结点指针域为空</span></span><br><span class="line">    <span class="keyword">return</span> OK;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="查找"   >          <a href="#查找" class="heading-link"><i class="fas fa-link"></i></a><a href="#查找" class="headerlink" title="查找"></a>查找</h2>              <h3 id="查找在线性表L中查找值为e的数据元素"   >          <a href="#查找在线性表L中查找值为e的数据元素" class="heading-link"><i class="fas fa-link"></i></a><a href="#查找在线性表L中查找值为e的数据元素" class="headerlink" title="查找在线性表L中查找值为e的数据元素"></a>查找<strong>在线性表</strong>L中查找值为e的数据元素</h3>      <p>LNode *LocataElem_L</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//在链表中查询值为e的节点</span></span><br><span class="line"><span class="function">LNode *<span class="title">LocateElem</span><span class="params">(LinkList L,Elemtype e)</span></span>&#123;</span><br><span class="line">    p=L-&gt;next;<span class="comment">//p指向第一个节点</span></span><br><span class="line">    <span class="keyword">while</span>(p &amp;&amp; p-&gt;data!=e)&#123;</span><br><span class="line">        p=p-&gt;next;</span><br><span class="line">        <span class="keyword">return</span> p; <span class="comment">// 找到返回节点指针，未找到返回 NULL</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h3 id="查找L中值为e的位置序号，失败返回0"   >          <a href="#查找L中值为e的位置序号，失败返回0" class="heading-link"><i class="fas fa-link"></i></a><a href="#查找L中值为e的位置序号，失败返回0" class="headerlink" title="查找L中值为e的位置序号，失败返回0"></a>查找L中值为e的位置序号，失败返回0</h3>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">LocateELem_L</span> <span class="params">(LinkList L，Elemtype e)</span> </span>&#123;</span><br><span class="line"> <span class="comment">//返回L中值为e的数据元素的位置序号，查找失败返回0 </span></span><br><span class="line">  p=L-&gt;next; j=<span class="number">1</span>;</span><br><span class="line">  <span class="keyword">while</span>(p &amp;&amp;p-&gt;data!=e)  </span><br><span class="line">        &#123;p=p-&gt;next;  j++;&#125;          </span><br><span class="line">  <span class="keyword">if</span>(p) <span class="keyword">return</span> j; <span class="comment">//p不为空说明找到了</span></span><br><span class="line">  <span class="keyword">else</span> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125; </span><br><span class="line"></span><br></pre></td></tr></table></div></figure>        <h2 id="插入（第i个节点前）"   >          <a href="#插入（第i个节点前）" class="heading-link"><i class="fas fa-link"></i></a><a href="#插入（第i个节点前）" class="headerlink" title="插入（第i个节点前）"></a>插入（第i个节点前）</h2>      <img src="../../../blog/artemis/source/images/image-20260106155743941.png" alt="image-20260106155743941" style="zoom:50%;" /><ul><li>创建p指向头结点</li><li>创建j&#x3D;0表示头结点是第0个节点</li><li>while循环寻找第i-1个节点并将p指向它</li><li>判断i的合法性，是否小于1或大于表长</li><li>生成新节点s，s的数据域置为e</li><li>新节点的next指向p的后继节点a1**（此时s还未接入链表）**</li><li>p的后继节点指向S</li></ul><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">ListInsert_L</span><span class="params">(LinkList &amp;L,<span class="type">int</span> i,ElemType e)</span></span>&#123; </span><br><span class="line">     p=L;<span class="comment">//注意，p=L-&gt;next是指向第一个节点，p=L是指向头结点</span></span><br><span class="line">    j=<span class="number">0</span>;<span class="comment">//头结点是第0个节点</span></span><br><span class="line">      <span class="keyword">while</span>(p&amp;&amp;j&lt;i−<span class="number">1</span>)&#123;</span><br><span class="line">          p=p-&gt;next;++j;</span><br><span class="line">      &#125;<span class="comment">//寻找第i−1个结点 ，并将p指向它</span></span><br><span class="line">      <span class="keyword">if</span>(!p||j&gt;i−<span class="number">1</span>)<span class="keyword">return</span> ERROR;<span class="comment">//i大于表长 + 1或者小于1  </span></span><br><span class="line">      s=<span class="keyword">new</span> LNode;<span class="comment">//生成新结点s </span></span><br><span class="line">      s-&gt;data=e;          <span class="comment">//将结点s的数据域置为e </span></span><br><span class="line">      s-&gt;next=p-&gt;next;      <span class="comment">//将结点s插入L中 </span></span><br><span class="line">      p-&gt;next=s; </span><br><span class="line">      <span class="keyword">return</span> OK; </span><br><span class="line">&#125;<span class="comment">//ListInsert_L </span></span><br></pre></td></tr></table></div></figure>        <h2 id="删除"   >          <a href="#删除" class="heading-link"><i class="fas fa-link"></i></a><a href="#删除" class="headerlink" title="删除"></a>删除</h2>      <p>删除第i个节点</p><ul><li><p>找到ai-1存储位置p</p></li><li><p>临时保存结点ai的地址在q中，以备释放</p></li><li><p>令p-&gt;next指向ai的后继节点ai+1(绕过ai)</p></li><li><p>将ai的值保存在e中</p></li><li><p>释放ai空间</p></li><li><img src="../../../blog/artemis/source/images/image-20260106160800014.png" alt="image-20260106160800014" style="zoom: 50%;" /></li></ul><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">ListDelete_L</span><span class="params">(LinkList &amp;L,<span class="type">int</span> i,ElemType &amp;e)</span></span>&#123;</span><br><span class="line">    p=L;j=<span class="number">0</span>; </span><br><span class="line">    <span class="keyword">while</span>(p-&gt;next &amp;&amp;j&lt;i<span class="number">-1</span>)&#123;<span class="comment">//寻找第i个结点，并令p指向其前驱 </span></span><br><span class="line">        p=p-&gt;next; ++j; </span><br><span class="line">    &#125; </span><br><span class="line">    <span class="keyword">if</span>(!(p-&gt;next)||j&gt;i<span class="number">-1</span>) <span class="keyword">return</span> ERROR; <span class="comment">//删除位置不合理 </span></span><br><span class="line">    q=p-&gt;next; <span class="comment">//临时保存被删结点的地址以备释放 </span></span><br><span class="line">    p-&gt;next=q-&gt;next; <span class="comment">//本来q后面才是ai+1,改成p后面</span></span><br><span class="line">    e=q-&gt;data; <span class="comment">//保存删除结点的数据域 </span></span><br><span class="line">    <span class="keyword">delete</span> q; <span class="comment">//释放删除结点的空间 </span></span><br><span class="line"> <span class="keyword">return</span> OK; </span><br><span class="line">&#125;<span class="comment">//ListDelete_L </span></span><br><span class="line"></span><br></pre></td></tr></table></div></figure><blockquote><p>关于p-&gt;next &#x3D; q-&gt;next的绕过原理</p><p>假设一个链表 头节点-&gt; A-&gt;B-&gt;C-&gt;NULL</p><p>p指向节点A,则p-&gt;next指向节点B，即q。</p><p>q-&gt;next指向c。</p><p>p-&gt;next&#x3D;q-&gt;next就是直接让A指向C</p></blockquote>        <h2 id="求表长"   >          <a href="#求表长" class="heading-link"><i class="fas fa-link"></i></a><a href="#求表长" class="headerlink" title="求表长"></a>求表长</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">ListLength_L</span><span class="params">(LinkList L)</span></span>&#123;</span><br><span class="line">    LinkList p;</span><br><span class="line">    p=L-&gt;next;<span class="comment">//p指向第一个结点</span></span><br><span class="line">    i=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span>(p)&#123;</span><br><span class="line">        i++;</span><br><span class="line">        p=p-&gt;next;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> i;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="判断是否为空-1"   >          <a href="#判断是否为空-1" class="heading-link"><i class="fas fa-link"></i></a><a href="#判断是否为空-1" class="headerlink" title="判断是否为空"></a>判断是否为空</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">ListEmpty</span><span class="params">(LinkList L)</span></span>&#123;</span><br><span class="line">    <span class="comment">//若L为空表，则返回1，否则返回0</span></span><br><span class="line">    <span class="keyword">if</span>(L-&gt;next)&#123;<span class="comment">//非空</span></span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="有序链表合并"   >          <a href="#有序链表合并" class="heading-link"><i class="fas fa-link"></i></a><a href="#有序链表合并" class="headerlink" title="有序链表合并"></a>有序链表合并</h1>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 函数功能：将两个非递减有序的带头结点的单链表La和Lb合并为一个新的非递减有序链表Lc</span></span><br><span class="line"><span class="comment">// 核心思想：通过指针操作，重用La和Lb的现有节点，不分配新的节点内存</span></span><br><span class="line"><span class="comment">// 参数说明：La, Lb-待合并的有序链表；Lc-合并后的新链表（引用传递）</span></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">MergeList_L</span><span class="params">(LinkList &amp;La, LinkList &amp;Lb, LinkList &amp;Lc)</span> </span>&#123;</span><br><span class="line">   <span class="comment">// 步骤1：初始化工作指针，跳过头结点，指向第一个数据节点</span></span><br><span class="line">   pa = La-&gt;next;  <span class="comment">// pa指向链表La的第一个数据节点（首元结点）</span></span><br><span class="line">   pb = Lb-&gt;next;  <span class="comment">// pb指向链表Lb的第一个数据节点</span></span><br><span class="line">   </span><br><span class="line">   <span class="comment">// 步骤2：设置合并后链表Lc的头结点，并初始化尾指针pc</span></span><br><span class="line">   pc = Lc = La;   <span class="comment">// 重用La的头结点作为Lc的头结点，pc作为Lc的当前尾指针</span></span><br><span class="line">   </span><br><span class="line">   <span class="comment">// 步骤3：核心循环 - 比较并合并两个链表的节点</span></span><br><span class="line">   <span class="comment">// 循环条件：两个链表都还有未处理的节点（pa和pb都不为NULL）</span></span><br><span class="line">   <span class="keyword">while</span>(pa &amp;&amp; pb) &#123;</span><br><span class="line">      <span class="comment">// 比较当前两个节点的大小，选择较小的节点链接到Lc</span></span><br><span class="line">      <span class="keyword">if</span>(pa-&gt;data &lt;= pb-&gt;data) &#123; </span><br><span class="line">         <span class="comment">// La的当前节点值较小或相等，将其链接到Lc末尾</span></span><br><span class="line">         pc-&gt;next = pa;  <span class="comment">// 将pa节点挂接到pc之后</span></span><br><span class="line">         pc = pa;        <span class="comment">// pc指针移动到新的尾节点pa</span></span><br><span class="line">         pa = pa-&gt;next;  <span class="comment">// pa指针后移，准备处理La的下一个节点</span></span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">else</span> &#123;</span><br><span class="line">         <span class="comment">// Lb的当前节点值较小，将其链接到Lc末尾</span></span><br><span class="line">         pc-&gt;next = pb;  <span class="comment">// 将pb节点挂接到pc之后</span></span><br><span class="line">         pc = pb;        <span class="comment">// pc指针移动到新的尾节点pb</span></span><br><span class="line">         pb = pb-&gt;next;  <span class="comment">// pb指针后移，准备处理Lb的下一个节点</span></span><br><span class="line">      &#125;</span><br><span class="line">   &#125; <span class="comment">// 结束循环时，pa和pb中至少有一个为NULL</span></span><br><span class="line">   </span><br><span class="line">   <span class="comment">// 步骤4：处理剩余节点 - 将未处理完的链表直接连接到Lc末尾</span></span><br><span class="line">   pc-&gt;next = pa ? pa : pb;  <span class="comment">// 如果pa不为空则连接La剩余部分，否则连接Lb剩余部分</span></span><br><span class="line">   </span><br><span class="line">   <span class="comment">// 步骤5：资源清理 - 释放Lb的头结点（数据节点已全部并入Lc）</span></span><br><span class="line">   <span class="keyword">delete</span> Lb;  <span class="comment">// Lb的头结点已不再需要，释放其内存空间</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>&#x2F;&#x2F;后面的大概率不考，难度比较高，只说了考单链表。有序链表合并</p>        <h2 id="前插法建单链表"   >          <a href="#前插法建单链表" class="heading-link"><i class="fas fa-link"></i></a><a href="#前插法建单链表" class="headerlink" title="前插法建单链表"></a>前插法建单链表</h2>      <p> 从一个空表开始重复读入数据</p><ul><li>生成新结点</li><li>将读入数据放到新节点</li><li>将该新节点插入到链表</li></ul><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">CreateList_F</span><span class="params">(LinkList &amp;L,<span class="type">int</span> n)</span></span>&#123;</span><br><span class="line">    L=<span class="keyword">new</span> LNode;</span><br><span class="line">    L-&gt;next=<span class="literal">NULL</span>;<span class="comment">//先建立一个带头结点的空链表</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=n;i&gt;<span class="number">0</span>;i--)&#123;</span><br><span class="line">        p=<span class="keyword">new</span> LNode;<span class="comment">//生成新节点</span></span><br><span class="line">        cin &gt;&gt;p-&gt;data;<span class="comment">//输入元素值</span></span><br><span class="line">        p-&gt;next=L-&gt;next;</span><br><span class="line">        L-&gt;next=p;<span class="comment">//插入到表头</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p><img src="/../../../blog/artemis/source/images/image-20260106151916295.png" alt="image-20260106151916295"></p>        <h2 id="尾插法建单链表"   >          <a href="#尾插法建单链表" class="heading-link"><i class="fas fa-link"></i></a><a href="#尾插法建单链表" class="headerlink" title="尾插法建单链表"></a>尾插法建单链表</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">CreateList_L</span><span class="params">(LinkList &amp;L,<span class="type">int</span> n)</span></span>&#123;</span><br><span class="line">    L=<span class="keyword">new</span> LNode;</span><br><span class="line">    L-&gt;next=<span class="literal">NULL</span>;</span><br><span class="line">    r=L;<span class="comment">//尾指针r指向头结点</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">0</span>;i&lt;n;i++)&#123;</span><br><span class="line">        p=<span class="keyword">new</span> LNode;</span><br><span class="line">        cin &gt;&gt;p-&gt;data;</span><br><span class="line">        p-&gt;next=<span class="literal">NULL</span>;<span class="comment">//将新创建节点p的指针域设置为NULL，表示它是链表的最后一个节点。</span></span><br><span class="line">        r-&gt;next=p;<span class="comment">//将新节点链接到链表尾部</span></span><br><span class="line">        r=p;<span class="comment">//r指向新的尾结点</span></span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="插入（指定位置插入新节点）"   >          <a href="#插入（指定位置插入新节点）" class="heading-link"><i class="fas fa-link"></i></a><a href="#插入（指定位置插入新节点）" class="headerlink" title="插入（指定位置插入新节点）"></a>插入（指定位置插入新节点）</h2>      <p>算法步骤</p><p>找到插入位置的前驱节点，生成一个新结点，新结点的数据域置为x，新结点* s的指针域指向结点ai，结点*p的指针域指向新节点 *s</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//在第i个位置插入新元素e，所有要在i-1个节点后面插入</span></span><br><span class="line"><span class="function">Status <span class="title">ListInsert</span><span class="params">(LinkList &amp;L,<span class="type">int</span> i,ElemType e)</span></span>&#123;</span><br><span class="line">    LNode *p=L; <span class="comment">//p指向头结点</span></span><br><span class="line">    <span class="type">int</span> j=<span class="number">0</span>;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//寻找第i-1个节点p</span></span><br><span class="line">    <span class="keyword">while</span>(p &amp;&amp; j&lt;i<span class="number">-1</span>)&#123;</span><br><span class="line">        p=p-&gt;next;</span><br><span class="line">        j++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//i小于0或大于表长加一</span></span><br><span class="line">    <span class="keyword">if</span>(!p || j&gt;i<span class="number">-1</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> ERROR;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//创建新节点</span></span><br><span class="line">    s=<span class="keyword">new</span> LNode;</span><br><span class="line">    s-&gt;data=e;</span><br><span class="line">    <span class="comment">//插入操作,在第i-1个节点也就是p节点后插入新节点</span></span><br><span class="line">    <span class="comment">//先让新节点指向p原来的下一个节点</span></span><br><span class="line">    s-&gt;next=p-&gt;next;<span class="comment">//如果s=p-&gt;next，指针s会直接指向p-&gt;next指向的节点，新节点会丢失</span></span><br><span class="line">    p-&gt;next =s;<span class="comment">//在让p指向新节点</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> OK;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="单向循环链表的操作及约瑟夫环"   >          <a href="#单向循环链表的操作及约瑟夫环" class="heading-link"><i class="fas fa-link"></i></a><a href="#单向循环链表的操作及约瑟夫环" class="headerlink" title="单向循环链表的操作及约瑟夫环"></a>单向循环链表的操作及约瑟夫环</h1>              <h2 id="初始化-1"   >          <a href="#初始化-1" class="heading-link"><i class="fas fa-link"></i></a><a href="#初始化-1" class="headerlink" title="初始化"></a>初始化</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 通常在头文件中这样定义</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> OK 1</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ERROR 0</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> OVERFLOW -1</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="type">int</span> Status;  <span class="comment">// 将Status定义为int类型</span></span><br><span class="line"><span class="function">Status <span class="title">InitList_CL</span><span class="params">(LinkList &amp;L)</span></span>&#123;</span><br><span class="line">    L=<span class="keyword">new</span> LNode;<span class="comment">//生成头结点</span></span><br><span class="line">    <span class="keyword">if</span>(!L) <span class="built_in">exit</span>(OVERLOW);<span class="comment">//内存分配失败</span></span><br><span class="line">    L-&gt;next=L;<span class="comment">//头结点的next指向自己，形成空环</span></span><br><span class="line">    <span class="keyword">return</span> OK;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="判断是否为空-2"   >          <a href="#判断是否为空-2" class="heading-link"><i class="fas fa-link"></i></a><a href="#判断是否为空-2" class="headerlink" title="判断是否为空"></a>判断是否为空</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">ListEmpty_CL</span><span class="params">(LinkList L)</span></span>&#123;</span><br><span class="line">    <span class="comment">//判断头结点的next是否指向自己</span></span><br><span class="line">    <span class="keyword">return</span> (L-&gt;next==L);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="结点p之前插入新结点s"   >          <a href="#结点p之前插入新结点s" class="heading-link"><i class="fas fa-link"></i></a><a href="#结点p之前插入新结点s" class="headerlink" title="结点p之前插入新结点s"></a>结点p之前插入新结点s</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">Status <span class="title">ListInsert_CL</span><span class="params">(LinkList &amp;L,LNode *p,EleType e)</span></span>&#123;</span><br><span class="line">    LNode *s=<span class="keyword">new</span> LNode;</span><br><span class="line">    <span class="keyword">if</span>(!s)<span class="keyword">return</span> ERROR;</span><br><span class="line">    s-&gt;data=e;</span><br><span class="line">    </span><br><span class="line">    s-&gt;next=p-&gt;next;<span class="comment">//新结点s指向p的后继</span></span><br><span class="line">    p-&gt;next=s;<span class="comment">//结点p指向新结点s</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">//如果p是尾结点，那么s就成为新的尾结点，其next头指向头结点L</span></span><br><span class="line">    <span class="keyword">return</span> OK;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="删除点p的后继节点"   >          <a href="#删除点p的后继节点" class="heading-link"><i class="fas fa-link"></i></a><a href="#删除点p的后继节点" class="headerlink" title="删除点p的后继节点"></a>删除点p的后继节点</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">Status <span class="title">ListDelete_CL</span><span class="params">(LinkList &amp;L,LNode *p,EleType &amp;e)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(p-&gt;next==L)<span class="keyword">return</span> ERRER;</span><br><span class="line">    <span class="comment">//p是尾结点，无后续可删</span></span><br><span class="line">    </span><br><span class="line">    LNode *q=p-&gt;next;<span class="comment">//q指向要删除的结点</span></span><br><span class="line">    e=q-&gt;data;<span class="comment">//保存被删除的结点位置</span></span><br><span class="line">    p-&gt;next=q-&gt;next;<span class="comment">//绕过要删除的结点</span></span><br><span class="line">    <span class="keyword">delete</span> q;<span class="comment">//释放内存</span></span><br><span class="line">    <span class="keyword">return</span> OK;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="合并链表"   >          <a href="#合并链表" class="heading-link"><i class="fas fa-link"></i></a><a href="#合并链表" class="headerlink" title="合并链表"></a>合并链表</h2>      <p><code>Ta</code>是链表a的尾指针，<code>Ta-&gt;next</code>指向链表a的头结点。</p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function">LinkList <span class="title">Connect</span><span class="params">(LinkList Ta,Linklist Tb)</span></span>&#123;</span><br><span class="line">    <span class="comment">//假设ta,tb都是非空单循环链表</span></span><br><span class="line">    p=Ta-&gt;next<span class="comment">//p存表头结点</span></span><br><span class="line">    Ta-&gt;next = Tb -&gt;next-&gt;next;<span class="comment">//tb表头连接Ta表尾</span></span><br><span class="line">    <span class="keyword">delete</span> Tb-&gt;next;<span class="comment">//释放tb表头结点,现在链表a的尾直接指向了链表b的首元结点，链表b原来的头结点（Tb-&gt;next）已经不再被需要。</span></span><br><span class="line">    Tb-&gt;next=p;<span class="comment">//修改指针</span></span><br><span class="line">    <span class="keyword">return</span> Tb;</span><br><span class="line">    <span class="comment">/*现在，整个链表的尾部是链表b原来的尾节点（即 Tb指向的节点）。</span></span><br><span class="line"><span class="comment">要让新链表成为循环链表，需要让尾节点的 next指针指向头结点。</span></span><br><span class="line"><span class="comment">p保存的正是链表a原来的头结点，现在它将成为合并后新链表的头结点。</span></span><br><span class="line"><span class="comment">这行代码让链表b的尾节点（Tb）的 next指针指向这个头结点，从而闭合整个链表，形成一个新的循环链表。</span></span><br><span class="line"><span class="comment">合并完成后，Tb指向的是新链表的尾节点。</span></span><br><span class="line"><span class="comment">函数返回 Tb，即返回新循环链表的尾指针。</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="约瑟夫环"   >          <a href="#约瑟夫环" class="heading-link"><i class="fas fa-link"></i></a><a href="#约瑟夫环" class="headerlink" title="约瑟夫环"></a>约瑟夫环</h2>      <p><img src="/../../../blog/artemis/source/images/image-20260106151944605.png" alt="image-20260106151944605"></p><figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">Josephus</span><span class="params">(<span class="type">int</span> n, <span class="type">int</span> m)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// 创建包含n个结点的循环链表</span></span><br><span class="line">    LinkList L, current, prev;</span><br><span class="line">    <span class="built_in">InitList_CL</span>(L);  <span class="comment">// 初始化循环链表</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 构建约瑟夫环</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        <span class="built_in">ListInsert_CL</span>(L, i, i);  <span class="comment">// 第i个人的编号为i</span></span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    current = L-&gt;next;  <span class="comment">// 从第一个人开始</span></span><br><span class="line">    prev = L;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">while</span>(n &gt; <span class="number">1</span>) &#123;</span><br><span class="line">        <span class="comment">// 数到第m个人</span></span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> count = <span class="number">1</span>; count &lt; m; count++) &#123;</span><br><span class="line">            prev = current;</span><br><span class="line">            current = current-&gt;next;</span><br><span class="line">            <span class="comment">// 如果遇到头结点，跳过</span></span><br><span class="line">            <span class="keyword">if</span>(current == L) &#123;</span><br><span class="line">                prev = current;</span><br><span class="line">                current = current-&gt;next;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 删除当前结点（淘汰这个人）</span></span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;出列的人是：%d\n&quot;</span>, current-&gt;data);</span><br><span class="line">        prev-&gt;next = current-&gt;next;</span><br><span class="line">        <span class="keyword">delete</span> current;</span><br><span class="line">        current = prev-&gt;next;</span><br><span class="line">        n--;</span><br><span class="line">        </span><br><span class="line">        <span class="comment">// 如果遇到头结点，跳过</span></span><br><span class="line">        <span class="keyword">if</span>(current == L) &#123;</span><br><span class="line">            current = current-&gt;next;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;最后剩下的人是：%d\n&quot;</span>, current-&gt;data);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="双向链表"   >          <a href="#双向链表" class="heading-link"><i class="fas fa-link"></i></a><a href="#双向链表" class="headerlink" title="双向链表"></a>双向链表</h1>              <h2 id="定义初始化"   >          <a href="#定义初始化" class="heading-link"><i class="fas fa-link"></i></a><a href="#定义初始化" class="headerlink" title="定义初始化"></a>定义初始化</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="keyword">struct</span> <span class="title class_">DuLNode</span>&#123;</span><br><span class="line">    EleType data;</span><br><span class="line">    <span class="keyword">struct</span> <span class="title class_">DuLNode</span> *prior;</span><br><span class="line">    <span class="keyword">struct</span> <span class="title class_">DuLNode</span> *next;</span><br><span class="line">&#125;DuLNode,*DuLLinkList</span><br><span class="line">    </span><br></pre></td></tr></table></div></figure>        <h2 id="插入"   >          <a href="#插入" class="heading-link"><i class="fas fa-link"></i></a><a href="#插入" class="headerlink" title="插入"></a>插入</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 函数功能：在带头结点的双向链表L中，第i个位置之前插入新元素e</span></span><br><span class="line"><span class="comment">// 参数说明：L-双向链表头指针（引用传递），i-插入位置，e-待插入元素</span></span><br><span class="line"><span class="comment">// 返回值：操作状态（OK-成功，ERROR-失败）</span></span><br><span class="line"><span class="function">Status <span class="title">ListInsert_DuL</span><span class="params">(DuLinkList &amp;L, <span class="type">int</span> i, ElemType e)</span> </span>&#123;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 步骤1：定位插入位置，获取第i个结点的指针p</span></span><br><span class="line">    <span class="comment">// 注意：这里是在第i个结点&quot;之前&quot;插入，所以p指向的是目标位置的后继结点</span></span><br><span class="line">    DuLNode *p;</span><br><span class="line">    <span class="keyword">if</span>(!(p = <span class="built_in">GetElemP_DuL</span>(L, i)))  <span class="comment">// 调用查找函数获取第i个结点的地址</span></span><br><span class="line">        <span class="keyword">return</span> ERROR;               <span class="comment">// 如果第i个结点不存在，返回错误</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 步骤2：创建新结点并赋值</span></span><br><span class="line">    DuLNode *s = <span class="keyword">new</span> DuLNode;  <span class="comment">// 动态分配新结点内存</span></span><br><span class="line">    s-&gt;data = e;               <span class="comment">// 将数据e存入新结点的数据域</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 步骤3：核心操作 - 四步指针修改，将新结点s插入到p结点之前</span></span><br><span class="line">    <span class="comment">// 这四步操作必须按顺序执行，确保链表不断链</span></span><br><span class="line">    </span><br><span class="line">    s-&gt;prior = p-&gt;prior;      <span class="comment">// 操作①：新结点s的前驱指向p原来的前驱结点</span></span><br><span class="line">    p-&gt;prior-&gt;next = s;       <span class="comment">// 操作②：p原前驱结点的后继指向新结点s</span></span><br><span class="line">    s-&gt;next = p;              <span class="comment">// 操作③：新结点s的后继指向p结点</span></span><br><span class="line">    p-&gt;prior = s;             <span class="comment">// 操作④：p结点的前驱指向新结点s</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> OK;  <span class="comment">// 插入成功，返回OK状态</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="删除-1"   >          <a href="#删除-1" class="heading-link"><i class="fas fa-link"></i></a><a href="#删除-1" class="headerlink" title="删除"></a>删除</h2>      <figure class="highlight cpp"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 函数功能：删除带头结点的双向链表L中第i个位置的元素，并通过e返回被删除的值</span></span><br><span class="line"><span class="comment">// 参数说明：L-双向链表头指针（引用传递），i-删除位置，e-用于返回被删除元素值的引用</span></span><br><span class="line"><span class="comment">// 返回值：操作状态（OK-成功，ERROR-失败）</span></span><br><span class="line"><span class="function">Status <span class="title">ListDelete_DuL</span><span class="params">(DuLinkList &amp;L, <span class="type">int</span> i, ElemType &amp;e)</span> </span>&#123;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 步骤1：定位要删除的结点，获取第i个结点的指针p</span></span><br><span class="line">    DuLNode *p;</span><br><span class="line">    <span class="keyword">if</span>(!(p = <span class="built_in">GetElemP_DuL</span>(L, i)))     <span class="comment">// 调用查找函数获取第i个结点的地址</span></span><br><span class="line">        <span class="keyword">return</span> ERROR;                 <span class="comment">// 如果第i个结点不存在，返回错误</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 步骤2：保存被删除结点的数据值</span></span><br><span class="line">    e = p-&gt;data;    <span class="comment">// 将待删除结点p的数据域值保存到参数e中，以便返回给调用者</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 步骤3：核心操作 - 两步指针修改，将结点p从链表中&quot;摘除&quot;</span></span><br><span class="line">    <span class="comment">// 关键思想：让p的前驱结点直接指向p的后继结点，绕过p本身</span></span><br><span class="line">    </span><br><span class="line">    p-&gt;prior-&gt;next = p-&gt;next;    <span class="comment">// 操作①：p前驱结点的后继指针指向p的后继结点</span></span><br><span class="line">    p-&gt;next-&gt;prior = p-&gt;prior;  <span class="comment">// 操作②：p后继结点的前驱指针指向p的前驱结点</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 步骤4：释放被删除结点的内存空间</span></span><br><span class="line">    <span class="keyword">delete</span> p;        <span class="comment">// 释放结点p占用的内存，防止内存泄漏</span></span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> OK;       <span class="comment">// 删除成功，返回OK状态</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h1 id="题目"   >          <a href="#题目" class="heading-link"><i class="fas fa-link"></i></a><a href="#题目" class="headerlink" title="题目"></a>题目</h1>      <ol><li></li></ol><p>对于循环队列，front&#x3D;(初始＋删除的位置)%size</p><p>rear&#x3D;(初始＋加入的位置)%size</p><p><img src="/../../../blog/artemis/source/images/image-20260103234414184.png" alt="image-20260103234414184"></p><ol start="2"><li></li></ol><p>顺序表中元素地址计算公式：<code>第i个元素地址 = 首地址 + (i-1) × 元素长度</code>。</p><p><img src="/../../../blog/artemis/source/images/image-20260103234551135.png" alt="image-20260103234551135"></p>]]></content>
      
      
      <categories>
          
          <category> 算法 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 数据结构 </tag>
            
            <tag> 线性表 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>树状数组</title>
      <link href="/2025/09/23/%E6%A0%91%E7%8A%B6%E6%95%B0%E7%BB%84/"/>
      <url>/2025/09/23/%E6%A0%91%E7%8A%B6%E6%95%B0%E7%BB%84/</url>
      
        <content type="html"><![CDATA[        <h2 id="什么是树状数组"   >          <a href="#什么是树状数组" class="heading-link"><i class="fas fa-link"></i></a><a href="#什么是树状数组" class="headerlink" title="什么是树状数组?"></a>什么是树状数组?</h2>      <p>它其实本质上和<strong>数组</strong>一样是一种<strong>数据结构</strong>，区别在于，它是<strong>树状</strong>的！（好像是废话）。</p><p>但是正是因为它是树状，所以它能高效的支持<strong>单点修改</strong>和<strong>区间查询</strong>！（并不是说它不能支持区间修改和单点查询。后面通过一些辅助数组和差分数组也可以实现）</p>        <h2 id="树状数组具体能干什么？"   >          <a href="#树状数组具体能干什么？" class="heading-link"><i class="fas fa-link"></i></a><a href="#树状数组具体能干什么？" class="headerlink" title="树状数组具体能干什么？"></a>树状数组具体能干什么？</h2>      <p>如果你想知道一个数组1-7的前缀和，你会怎么做？</p><figure class="highlight c++"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">1</span>;i&lt;=<span class="number">7</span>;i++)&#123;</span><br><span class="line">sum+=a[i];</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>朴实无华的循环。时间复杂度O(n)</p><p>你也许会想，这还能玩出朵花来吗？当然，请相信代码世界有着无穷的创造力。</p><p>现在如果我告诉你，我知道a[1-4],a[5-6],a[7]呢？</p><p>那么当然就是这三个数的相加了。这就是树状数组的关键</p><p><u><strong>我们总能将一段长n的区间拆成不多于logn段区间</strong></u></p><p>接下来我将附上一张原理图，让你直观了解什么是树状。</p><p><img src="/images/image-20250923200239382.png" alt="image-20250923200239382"></p><p><img src="/../images/image-20250923205827539.png" alt="image-20250923205827539"></p><p>由图可知，减少时间复杂度的关键就在于c数组，那么问题来了</p>        <h2 id="c-x-管辖的区间到底是什么？（lowbit引入预告）"   >          <a href="#c-x-管辖的区间到底是什么？（lowbit引入预告）" class="heading-link"><i class="fas fa-link"></i></a><a href="#c-x-管辖的区间到底是什么？（lowbit引入预告）" class="headerlink" title="c[x]管辖的区间到底是什么？（lowbit引入预告）"></a>c[x]管辖的区间到底是什么？（lowbit引入预告）</h2>      <p>树状数组中我们规定，c[x]管辖的区间是<strong>2的k次方</strong>（k是数的二进制表示中，最低位的1所在的位置）。</p><p>那么2的k次方就是x的二进制表示中最低位的1以及后面所有0组成的数字。</p><p>例如c88管辖哪个区间呢？它的二进制是<strong>01011000</strong>.那么它最低位的1以及后面的0组成的是<strong>1000</strong>，所以管辖<strong>八个</strong>元素。代表a[81-88]。对于<strong>1000</strong>，我们叫他，<strong>lowbit(88)。</strong></p>        <h2 id="代码如何实现lowbit-x"   >          <a href="#代码如何实现lowbit-x" class="heading-link"><i class="fas fa-link"></i></a><a href="#代码如何实现lowbit-x" class="headerlink" title="代码如何实现lowbit(x)"></a>代码如何实现lowbit(x)</h2>      <p>这个就涉及到位运算知识了，补码反码的运算。这里不说原理了（犯懒）。</p><figure class="highlight c"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="title function_">lowbit</span><span class="params">(<span class="type">int</span> x)</span>&#123;</span><br><span class="line"> <span class="keyword">return</span> x&amp;-x</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>就是这么的朴实无华）</p>        <h2 id="如何通过lowbit-x-实现区间查询"   >          <a href="#如何通过lowbit-x-实现区间查询" class="heading-link"><i class="fas fa-link"></i></a><a href="#如何通过lowbit-x-实现区间查询" class="headerlink" title="如何通过lowbit(x)实现区间查询"></a>如何通过lowbit(x)实现区间查询</h2>      <p>前面我们提到，树状数组可以实现区间查询有了lowbit之后，我们就可以轻松获得c[x]对应的a[]有几个，从而丝滑的实现区间查询了。</p><p>回顾上面提到的a[4–7]，</p><p>c7–lowbit(7)&#x3D;1</p><p>c6–lowbit(6)&#x3D;2</p><p>c4–lowbit(4)&#x3D;4</p><p>令x不断地减去lowbit(x)直到等于0，就说明我们要找的数都找完了。</p><p>代码实现如下</p><figure class="highlight c"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="title function_">getsum</span><span class="params">(<span class="type">int</span> x)</span> &#123;  <span class="comment">// a[1]..a[x]的和</span></span><br><span class="line">  <span class="type">int</span> ans = <span class="number">0</span>;</span><br><span class="line">  <span class="keyword">while</span> (x &gt; <span class="number">0</span>) &#123;</span><br><span class="line">    ans = ans + c[x];</span><br><span class="line">    x = x - lowbit(x);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> ans;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="如何通过lowbit-x-实现单点修改？"   >          <a href="#如何通过lowbit-x-实现单点修改？" class="heading-link"><i class="fas fa-link"></i></a><a href="#如何通过lowbit-x-实现单点修改？" class="headerlink" title="如何通过lowbit(x)实现单点修改？"></a>如何通过lowbit(x)实现单点修改？</h2>      <p>如果是a数组，那么单点修改不过是一个等于号的赋值操作。但是由于我们是通过c数组来计算以达到logn实现区间查询的目的，那么我们现在应该思考的问题是</p><p><strong>如何通过修改c数组来单点修改a数组</strong></p><p>不妨联想一下我们如何实现Sn-&gt;an<br>$$<br>Sn-Sn-1&#x3D;an<br>$$<br>如果想要an +1，那我们只需要Sn +1.如果想要a(n-1) +1,那我们只要S(n-1)+1</p><p>(很简单的道理，1，2，3，4，5这个数组，我想要4变成6，那么S5 会变成17，S4会变成12，S3 是6不变。S4-S3&#x3D;a4&#x3D;6)</p><p>Cn其实也是另一种形式的Sn,只是他不是从1到n，但是他也是有规律的，这个规律就是lowbit(x)。</p><p><strong>c[x]管理的区间是 [x - lowbit(x) + 1, x]</strong></p><p>我们通过例子不难看出，本质上就是，谁包含我，我加上一个数，包含我的它也要加上一个数。</p><p>我们只需要通过lowbit向上搜寻，我们要加上的单点在哪个节点上即可。</p><p>以c[6]为例</p><ul><li><code>c[6]</code>管理 <code>[5, 6]</code>（lowbit(6)&#x3D;2）</li><li><code>c[8(6+2)]</code>管理 <code>[1, 8]</code>（lowbit(8)&#x3D;8）</li><li><code>c[16(8+8)]</code>管理 <code>[1, 16]</code>（因为 <code>16 - 16 + 1 = 1</code>）</li></ul><p>(还可以往上延申</p><p>话不多说，献上代码！</p><figure class="highlight c"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">void</span> <span class="title function_">add</span><span class="params">(<span class="type">int</span> x, <span class="type">int</span> k)</span> &#123;</span><br><span class="line">  <span class="keyword">while</span> (x &lt;= n) &#123;  <span class="comment">// 不能越界</span></span><br><span class="line">    c[x] = c[x] + k;</span><br><span class="line">    x = x + lowbit(x);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="来练练手叭（恭喜你已经学会了单点修改和区间查询）"   >          <a href="#来练练手叭（恭喜你已经学会了单点修改和区间查询）" class="heading-link"><i class="fas fa-link"></i></a><a href="#来练练手叭（恭喜你已经学会了单点修改和区间查询）" class="headerlink" title="来练练手叭（恭喜你已经学会了单点修改和区间查询）"></a>来练练手叭（恭喜你已经学会了单点修改和区间查询）</h2>      <img src="../images/image-20250924085013250.png" alt="image-20250924085013250" style="zoom:67%;" /><p>这是一道模板题，只要你理解了原理（不理解好像也没问题）就能丝滑的写出。<span class="exturl"><a class="exturl__link"   href="https://loj.ac/p/130" >#130. 树状数组 1 ：单点修改，区间查询 - 题目 - LibreOJ</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span>，附上题目链接，快去试试吧！</p><figure class="highlight c++"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ll long long</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">1e6</span> + <span class="number">5</span>;</span><br><span class="line"><span class="type">long</span> <span class="type">long</span> n, q, x, y, a, b, c[N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">lowbit</span><span class="params">(<span class="type">int</span> x)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> x &amp; -x;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function">ll <span class="title">getSum</span><span class="params">(<span class="type">int</span> x)</span> </span>&#123;</span><br><span class="line">    ll ans = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span> (x &gt; <span class="number">0</span>) &#123;</span><br><span class="line">        ans = ans + c[x];</span><br><span class="line">        x = x - <span class="built_in">lowbit</span>(x);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> ans;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">add</span><span class="params">(<span class="type">int</span> x, <span class="type">int</span> k)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">while</span> (x &lt;= n) &#123;</span><br><span class="line">        c[x] = c[x] + k;</span><br><span class="line">        x = x + <span class="built_in">lowbit</span>(x);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">solve</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    cin &gt;&gt; y &gt;&gt; a &gt;&gt; b;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (y == <span class="number">1</span>) &#123;</span><br><span class="line">        <span class="built_in">add</span>(a, b);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        cout &lt;&lt; <span class="built_in">getSum</span>(b) - <span class="built_in">getSum</span>(a - <span class="number">1</span>) &lt;&lt; endl;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    ios::<span class="built_in">sync_with_stdio</span>(<span class="literal">false</span>);</span><br><span class="line">    cin.<span class="built_in">tie</span>(<span class="number">0</span>);</span><br><span class="line">    cout.<span class="built_in">tie</span>(<span class="number">0</span>);</span><br><span class="line">    <span class="built_in">memset</span>(c, <span class="number">0</span>, <span class="built_in">sizeof</span>(c));</span><br><span class="line">    cin &gt;&gt; n &gt;&gt; q;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        cin &gt;&gt; x;</span><br><span class="line">        <span class="built_in">add</span>(i, x);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span> (q--) &#123;</span><br><span class="line">        <span class="built_in">solve</span>();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="如何实现区间修改，单点查询？"   >          <a href="#如何实现区间修改，单点查询？" class="heading-link"><i class="fas fa-link"></i></a><a href="#如何实现区间修改，单点查询？" class="headerlink" title="如何实现区间修改，单点查询？"></a>如何实现区间修改，单点查询？</h2>      <p>前面提到过，树状数组在辅助数组的帮助下可以实现区间修改。那么在我不提示的情况下，你不妨先思考几分钟，<strong>让子弹飞一会</strong>。</p><p>让我来猜一猜你现在是不是已经有了一个朴素的想法。</p><figure class="highlight c++"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span>(<span class="type">int</span> i=l;i&lt;=r;i++)&#123;</span><br><span class="line">   <span class="type">int</span> k;</span><br><span class="line">   cin &gt;&gt;k;</span><br><span class="line">   <span class="built_in">add</span>(i,k);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>但是这样，时间复杂度不是又上来了吗？那你何必费这么大功夫折腾树状数组（狗狗问号脸）</p><p>如果你现在一头雾水，毫无灵感这很正常，是因为你还没有遇见它–<strong>差分数组</strong>）</p>        <h4 id="什么是差分数组呢？我们这里为什么会想到构造它？"   >          <a href="#什么是差分数组呢？我们这里为什么会想到构造它？" class="heading-link"><i class="fas fa-link"></i></a><a href="#什么是差分数组呢？我们这里为什么会想到构造它？" class="headerlink" title="什么是差分数组呢？我们这里为什么会想到构造它？"></a>什么是差分数组呢？我们这里为什么会想到构造它？</h4>      <p>不妨回顾一下我们前面我们是如何降低时间复杂度的。</p><p><strong>其实就是构造一个关联的数组</strong>。那么除了树状拆分来得到c数组，我们其实还可以通过<strong>逆向求和</strong>的方式得到d数组也就是差分数组。</p><p>什么叫逆向求和?你可以通过an累加得到Sn，自然也可以通过Sn递减得到an.</p><p>Sn是an的求和数组，那么an也可以成为另一个人的求和数组。<br>$$<br>an-a(n-1)&#x3D;dn<br>$$<br>这就是差分数组。其实听起来很简单吧。（事实上也很简单）</p><p>我们利用add方法来构造它</p><figure class="highlight c++"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++)</span><br><span class="line">        cin &gt;&gt; a[i], <span class="built_in">add</span>(i, a[i] - a[i - <span class="number">1</span>]);</span><br></pre></td></tr></table></div></figure><p>难的是，我们如何利用它把区间修改 转化成单点修改。</p><p>假设a数组 2 2 4 5 8 10</p><p>那么d数组 2 0 2 1 3 2</p><p>我现在想把a[2-3]加2，那么</p><p>a数组  2 4 6 5 8 10</p><p>d数组  2 2 2 -1 3 2</p><p>你动手算了一遍就会发现一个规律，其实我们区间修改[l-r]时，对于d数组来说，<strong>变的只有d[l]和d[r+1]。</strong></p><p>这并不是什么神奇规律，这是差分数组的必然。a[l]作为第一个增大的元素，d数组只能依靠d[l]增长来让总和等于a[l]。而d[l]增大后x，意味着a[l]往后的数其实都会增大x。（就像a2增大2，那s2后面的数也都会增大2）.</p><p>问题来了，我们是要实现一个区间，而不是从一个数往后都增大。那其实也很简单。</p><p>在右界减去一个x不久好了？那么从r往后的数都会减去一个x。自然就实现了区间修改。</p>        <h4 id="总结！"   >          <a href="#总结！" class="heading-link"><i class="fas fa-link"></i></a><a href="#总结！" class="headerlink" title="总结！"></a>总结！</h4>      <p><strong>差分数组是一种常见的处理区间修改的技术：</strong></p><ul><li><strong>定义差分数组d，其中d[i] &#x3D; a[i] - a[i-1]（a[0]&#x3D;0）</strong></li><li><strong>区间[l,r]加x的操作可以转化为：</strong><ul><li><strong>d[l] +&#x3D; x</strong></li><li><strong>d[r+1] -&#x3D; x</strong></li></ul></li></ul><p>也许你会疑惑怎么就总结了，单点查询不是还没讲吗？有了d数组的情况下，我们如何求a?</p><p>这不就是朴实无华的 已知an求Sn吗。求个前缀和就好啦。<br>$$<br>a[i] &#x3D; getsum(i) &#x3D; d[1] + d[2] + … + d[i]<br>$$<br>也许你会疑惑，这时间复杂度不是又上来了吗？</p><p>看到求这个前缀和你有没有觉得熟悉呢，朋友。这不就是我们一开始引入树状数组要解决的问题吗？也就是前缀和查询功能。</p><p>那么再根据d数组构建一个属于它的树状数组tree，问题就迎刃而解了！</p><p>话不多说，奉上题目代码</p><p>[题目链接](<span class="exturl"><a class="exturl__link"   href="https://loj.ac/p/131" >#131. 树状数组 2 ：区间修改，单点查询 - 题目 - LibreOJ</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span>)</p><p><img src="/../images/image-20250924095109141.png" alt="image-20250924095109141"></p><p>AC代码</p><figure class="highlight c++"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ll long long</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">1e6</span> + <span class="number">5</span>;</span><br><span class="line">ll n, q, opt, x, l, r, tree[N], a[N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">lowbit</span><span class="params">(<span class="type">int</span> x)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> x &amp; -x;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function">ll <span class="title">getsum</span><span class="params">(<span class="type">int</span> x)</span> </span>&#123;</span><br><span class="line">    ll ans = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span> (x &gt; <span class="number">0</span>) &#123;</span><br><span class="line">        ans += tree[x];</span><br><span class="line">        x -= <span class="built_in">lowbit</span>(x);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> ans;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">add</span><span class="params">(<span class="type">int</span> x, ll k)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">while</span> (x &lt;= n) &#123;</span><br><span class="line">        tree[x] += k;</span><br><span class="line">        x += <span class="built_in">lowbit</span>(x);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">solve</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    cin &gt;&gt; opt;</span><br><span class="line">    <span class="keyword">if</span>(opt == <span class="number">1</span>) &#123;</span><br><span class="line">        cin &gt;&gt; l &gt;&gt; r &gt;&gt; x;</span><br><span class="line">        <span class="built_in">add</span>(l, x);</span><br><span class="line">        <span class="keyword">if</span>(r + <span class="number">1</span> &lt;= n) &#123;  <span class="comment">// 防止越界</span></span><br><span class="line">            <span class="built_in">add</span>(r + <span class="number">1</span>, -x);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> &#123;</span><br><span class="line">        cin &gt;&gt; x;</span><br><span class="line">        cout &lt;&lt; <span class="built_in">getsum</span>(x) &lt;&lt; <span class="string">&#x27;\n&#x27;</span>;  </span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    ios::<span class="built_in">sync_with_stdio</span>(<span class="literal">false</span>);</span><br><span class="line">    cin.<span class="built_in">tie</span>(<span class="number">0</span>);</span><br><span class="line">    cout.<span class="built_in">tie</span>(<span class="number">0</span>);</span><br><span class="line">    <span class="built_in">memset</span>(tree, <span class="number">0</span>, <span class="built_in">sizeof</span>(tree));  <span class="comment">// 初始化tree数组</span></span><br><span class="line">    </span><br><span class="line">    cin &gt;&gt; n &gt;&gt; q;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        cin &gt;&gt; a[i];</span><br><span class="line">        <span class="built_in">add</span>(i, a[i] - (i == <span class="number">1</span> ? <span class="number">0</span> : a[i<span class="number">-1</span>]));  <span class="comment">// 更安全的差分初始化</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span> (q--) &#123;</span><br><span class="line">        <span class="built_in">solve</span>();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure>        <h2 id="最后关卡，如何实现区间修改，区间查询？"   >          <a href="#最后关卡，如何实现区间修改，区间查询？" class="heading-link"><i class="fas fa-link"></i></a><a href="#最后关卡，如何实现区间修改，区间查询？" class="headerlink" title="最后关卡，如何实现区间修改，区间查询？"></a>最后关卡，如何实现区间修改，区间查询？</h2>      <p>恭喜你已经到了一维数组这一关的boss关卡，但我想说，这一关只和数学推导有关了。</p><p>区间修改我们无疑问的仍然使用差分数组，那么如何用差分数组实现区间查询呢？</p><p>原始数组<code>a</code>的前缀和可以表示为：<br>$$<br>sum[1..x] &#x3D; Σ(i&#x3D;1 to x) a[i]<br>$$<br>使用差分数组<code>d</code>（其中<code>d[i] = a[i] - a[i-1]</code>，<code>a[0]=0</code>）：<br>$$<br>sum[1..x] &#x3D; Σ(i&#x3D;1 to x) Σ(j&#x3D;1 to i) d[j]<br>          &#x3D; Σ(j&#x3D;1 to x) (x - j + 1) * d[j]<br>          &#x3D; (x+1) * Σ(j&#x3D;1 to x) d[j] - Σ(j&#x3D;1 to x) j * d[j]<br>$$<br>然后丝滑的<br>$$<br>sum[l..r] &#x3D; sum[1..r] - sum[1..l-1]<br>$$<br>我们用两个树状数组维护sum[1-x]最后的两项结果即可<br>$$<br>(x+1) * Σ(j&#x3D;1 to x) d[j] - Σ(j&#x3D;1 to x) j * d[j]<br>$$<br>这正是我们使用两个树状数组维护的内容：</p><ul><li><code>tree1</code>维护<code>Σd[j]</code></li><li><code>tree2</code>维护<code>Σj * d[j]</code></li></ul><p><span class="exturl"><a class="exturl__link"   href="https://loj.ac/p/132" >题目链接</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p><p>附上AC代码</p><figure class="highlight c++"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;bits/stdc++.h&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="keyword">using</span> ll = <span class="type">long</span> <span class="type">long</span>;</span><br><span class="line"><span class="type">const</span> ll N = <span class="number">1e6</span> + <span class="number">5</span>;</span><br><span class="line">ll t1[N], t2[N];  <span class="comment">// 两个树状数组</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">inline</span> ll <span class="title">lowbit</span><span class="params">(ll x)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> x &amp; (-x);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="type">void</span> <span class="title">add</span><span class="params">(ll t[], ll k, ll x)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">for</span> (ll i = k; i &lt; N; i += <span class="built_in">lowbit</span>(i)) &#123;</span><br><span class="line">        t[i] += x;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">inline</span> ll <span class="title">sum</span><span class="params">(ll t[], ll x)</span> </span>&#123;</span><br><span class="line">    ll ans = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (ll i = x; i &gt; <span class="number">0</span>; i -= <span class="built_in">lowbit</span>(i)) &#123;</span><br><span class="line">        ans += t[i];</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> ans;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    ios::<span class="built_in">sync_with_stdio</span>(<span class="literal">false</span>);</span><br><span class="line">    cin.<span class="built_in">tie</span>(<span class="literal">nullptr</span>);</span><br><span class="line"></span><br><span class="line">    ll n, m;</span><br><span class="line">    cin &gt;&gt; n &gt;&gt; m;</span><br><span class="line"></span><br><span class="line">    ll last = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i &lt;= n; i++) &#123;</span><br><span class="line">        ll x;</span><br><span class="line">        cin &gt;&gt; x;</span><br><span class="line">        <span class="built_in">add</span>(t1, i, x - last);</span><br><span class="line">        <span class="built_in">add</span>(t2, i, i * (x - last));</span><br><span class="line">        last = x;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span> (m--) &#123;</span><br><span class="line">        ll op;</span><br><span class="line">        cin &gt;&gt; op;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (op == <span class="number">1</span>) &#123;</span><br><span class="line">            ll l, r, x;</span><br><span class="line">            cin &gt;&gt; l &gt;&gt; r &gt;&gt; x;</span><br><span class="line">            <span class="built_in">add</span>(t1, l, x);</span><br><span class="line">            <span class="built_in">add</span>(t1, r + <span class="number">1</span>, -x);</span><br><span class="line">            <span class="built_in">add</span>(t2, l, l * x);</span><br><span class="line">            <span class="built_in">add</span>(t2, r + <span class="number">1</span>, -(r + <span class="number">1</span>) * x);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            ll l, r;</span><br><span class="line">            cin &gt;&gt; l &gt;&gt; r;</span><br><span class="line">            ll prefix_r = (r + <span class="number">1</span>) * <span class="built_in">sum</span>(t1, r) - <span class="built_in">sum</span>(t2, r);</span><br><span class="line">            ll prefix_l = l * <span class="built_in">sum</span>(t1, l - <span class="number">1</span>) - <span class="built_in">sum</span>(t2, l - <span class="number">1</span>);</span><br><span class="line">            cout &lt;&lt; prefix_r - prefix_l &lt;&lt; <span class="string">&quot;\n&quot;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>是的，到这里，区间修改，单点修改，区间查询，单点查询已经玩不起花了。</p><p>但是树状数组还没有结束！</p><p>因为这只是一维数组。<strong>树状数组还有plus版本，也就是二维数组。</strong></p><p><strong>欲知后事如何，请听下回分解~</strong></p>]]></content>
      
      
      <categories>
          
          <category> 算法 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> 算法 </tag>
            
            <tag> acm </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>候鸟衔的信（三行情诗）</title>
      <link href="/2025/09/22/%E4%B8%89%E8%A1%8C%E6%83%85%E8%AF%97/"/>
      <url>/2025/09/22/%E4%B8%89%E8%A1%8C%E6%83%85%E8%AF%97/</url>
      
        <content type="html"><![CDATA[<p>三行情诗是一个很有意思的发明。人们对于情意，总是想诉说很多。然而如果只让你写三行，你会写什么呢？</p><p>（不定时更新）</p>        <h1 id="其一"   >          <a href="#其一" class="heading-link"><i class="fas fa-link"></i></a><a href="#其一" class="headerlink" title="其一"></a>其一</h1>      <p>在我的眸上，<br>雕刻你的脸庞，<br>自此众生皆你模样。</p>        <h1 id="其二"   >          <a href="#其二" class="heading-link"><i class="fas fa-link"></i></a><a href="#其二" class="headerlink" title="其二"></a>其二</h1>      <p>看雪是你，听风是你，<br>你居心上，<br>才在天地。</p>        <h1 id="其三"   >          <a href="#其三" class="heading-link"><i class="fas fa-link"></i></a><a href="#其三" class="headerlink" title="其三"></a>其三</h1>      <p>毕生所逐不过诗与远方<br>而你仅仅在我眼前<br>便是绝世的诗篇</p>        <h1 id="其四"   >          <a href="#其四" class="heading-link"><i class="fas fa-link"></i></a><a href="#其四" class="headerlink" title="其四"></a>其四</h1>      <p>于江海里窥你面容<br>在朝云中与你相拥<br>我落笔写下相逢</p>        <h1 id="其五"   >          <a href="#其五" class="heading-link"><i class="fas fa-link"></i></a><a href="#其五" class="headerlink" title="其五"></a>其五</h1>      <p>邂逅你于清晨<br>失去你于黄昏<br>愿重逢时不是故人</p>        <h1 id="其六"   >          <a href="#其六" class="heading-link"><i class="fas fa-link"></i></a><a href="#其六" class="headerlink" title="其六"></a>其六</h1>      <p>想给你念诗<br>想为你写诗<br>想和你成诗</p>        <h1 id="其七"   >          <a href="#其七" class="heading-link"><i class="fas fa-link"></i></a><a href="#其七" class="headerlink" title="其七"></a>其七</h1>      <p>总是有些自我的想法，</p><p>比如你似乎不属于这世间，</p><p>而如今只是为了和我遇见。</p>]]></content>
      
      
      <categories>
          
          <category> 创作 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> 情诗 </tag>
            
            <tag> 写作 </tag>
            
            <tag> 现代诗 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>在云上出现的字（读书摘抄）</title>
      <link href="/2025/09/22/%E4%BA%91%E4%B8%8A%E5%87%BA%E7%8E%B0%E7%9A%84%E5%AD%97/"/>
      <url>/2025/09/22/%E4%BA%91%E4%B8%8A%E5%87%BA%E7%8E%B0%E7%9A%84%E5%AD%97/</url>
      
        <content type="html"><![CDATA[<p><strong>不定时</strong>更新看到的喜欢的句子，仰头方见，故言云上。也许会附上一些自己的感悟</p><ul><li><p><strong>我与我，周旋久，宁作我。</strong></p><blockquote><p>我仍记得第一次看到这句话，是在世说新语上。</p><p>桓公少与殷侯齐名，常有竞心。桓问殷：“卿何如我？”殷云：“<strong>我与我，周旋久，宁作我！</strong>”</p><p>世俗意义上，恒温以一个胜利者的姿态向殷浩问，此时的你和我相比，怎么样？</p><p>殷只是淡淡说了句，我宁愿做我自己。</p><p>彼时只惊叹于殷的宠辱不惊，气魄非凡。现在对这句话有了更多的感慨。</p><p>你是世上最了解自己的人，你知道如何应对自己的悲伤，你知道你在受伤时的脆弱。你知道如何克制你人性中的恶，如何选择让自己相处舒适的朋友。你知道你的拖延，你的犹豫，你的果决，你知道你的爱意会如何汹涌，知道如何抑制自己的感情。你无数次在内心挣扎，脑海里两种声音在打架。</p><p>我与我，周旋久。</p></blockquote></li><li><p><strong>当你看过人性的复杂，便不会轻言善恶。</strong></p><blockquote><p>并不是第一次看见这句话，但我对这句话有深层次的理解，是看完万历十五年后。便不去论张居正申时行，哪怕是历史上没能有些大作为的，也难以评说。在正德皇帝为祖母祭祀时，看到地上满是泥水，便免了大臣下跪。然而有位大臣舒芬却以此为题，在奏章上引用孔孟之道的孝道来谴责正德的行为。一时之间，名扬史册。这到底是讪君卖直求名，还是迂腐到不可理喻？抑或是所谓卫道者的直勇？</p></blockquote></li><li><p><strong>我和这个世界有过情人般的争吵。</strong></p><blockquote><p>谈一段恋爱之后才能真正理解这段话</p></blockquote></li><li><p><strong>我之所以写徐霞客，是想告诉你，所谓百年功名，千秋霸业，万古流芳，与一件事情相比，其实都算不了什么，这件事情就是——用你喜欢的方式度过一生。</strong></p><blockquote><p>你总会遇见这样一个问题，人生有什么意义？你为什么而活？每次看见这类问题，我以为都没有比当年明月这句话更好的回答了。我活着，是我想用自己的方式过完这一生，我想去看无垠的深海，无边的沙漠，北极的极光，西藏的神山。我想去寻找我所爱的人，让我灵魂为之共鸣的灵魂，我想读遍千古这诗文，坐在张岱身旁看湖心亭的雪，站在东坡上听那一场穿林打叶的雨。</p></blockquote></li><li><p><strong>问菩萨为何倒座</strong><br><strong>叹众生不肯回头。</strong></p></li><li><p><strong>逢人不说人间事， 便是人间无事人。</strong></p></li><li><p><strong>我只愿你面朝大海，春暖花开。</strong></p></li><li><p><strong>你承诺过的月亮，还是没有出现，而我无眠，或者，我只是衣单天寒的，替你多爱了一夜人间。</strong></p></li><li><p><strong>我有时看山不是山，看太阳不是太阳。我看天空是大海，我看大海是宇宙。我的脑中可以飞出蝴蝶，再开出繁花。我掌管自己的草木枯荣，我包容万物的悲欢离合。</strong></p></li><li><p><strong>为天地立心，为生民立命，为往圣继绝学，为万世开太平。</strong></p><blockquote><p>横渠四句，气概压古今。</p></blockquote></li><li><p><strong>柳下系舟犹未稳，能几日，又中秋。</strong></p></li><li><p><strong>诗万首，酒千觞，几曾着眼看候王。</strong></p></li><li><p><strong>在干净的院子里读你的诗歌。这人间情事恍惚如突然飞过的麻雀儿</strong><br><strong>而光阴皎洁。我不适宜肝肠寸断</strong><br><strong>如果给你寄一本书，我不会寄给你诗歌</strong><br><strong>我要给你一本关于植物，关于庄稼的告诉你稻子和稗子的区别</strong><br><strong>告诉你一棵稗子提心吊胆的春天</strong></p></li><li><p><strong>此地长眠者 声名水上书</strong></p></li><li><p><strong>所见诸佛，皆由己心。</strong></p></li><li><p><strong>松花酿酒，春水煎茶。</strong></p></li><li><p><strong>不是风动，不是幡动，仁者心动。</strong></p></li><li><p><strong>行到水穷处，坐看云起时。</strong></p></li><li><p><strong>我们吞咽了太多意义，其实生命只需要呼吸</strong></p></li><li><p><strong>生火就是生火，砍柴就是砍柴，它们不是为了做饭，它们只是生火砍柴。</strong></p></li></ul>]]></content>
      
      
      <categories>
          
          <category> 创作 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> 书籍 </tag>
            
            <tag> 读书 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>在河里漂的小纸条（作者写的乱七八糟的文案）</title>
      <link href="/2025/09/22/%E6%96%87%E6%A1%88/"/>
      <url>/2025/09/22/%E6%96%87%E6%A1%88/</url>
      
        <content type="html"><![CDATA[<p>有些句子，会像某个时间，流水一样流过你的脑海，也许抓得住，也许抓不住。它们没头没尾，有时也显得做作。但是都是思想在流动的证明。朋友，希望你也珍视你脑海中一闪而过的灵感。这也是你的一部分。如果你能在这条河中看到你愿意为之停留的纸条，那么固然是我的幸运。（不定时持续更新）。</p><p>之前作者有一个专门的笔记本记录这些，只可惜也许找不到了。只能在记忆里搜寻。这里同样是从六七年前开始写的句子。</p><ul><li><p><strong>那时的我们太过执着，凡事总要论个对错，求个结果。</strong></p></li><li><p><strong>叹苍天空付，身随流俗，江郎心失非才尽，半身傲才半身苦。</strong></p></li><li><p><strong>希望我没有来生，唯有此时。</strong></p></li><li><p><strong>我第一次看见风，是在你的发间，但我没有看风。</strong></p></li><li><p><strong>回忆把人困在那里，却又给人栖息之地。</strong></p></li><li><p><strong>不为明月，借阳而耀。自非溪流，无羡沧海。</strong></p></li><li><p><strong>觉得许久未见，也非一别经年，应怪太过思念。</strong></p></li><li><p><strong>我们还没有看过江上的日出，月光初照的洞庭。甚至爱意未曾来得及说出口，盛夏的风便把我们吹散，要为这荒诞的青春画上句号。</strong></p></li><li><p><strong>无香早入海棠耳，未见花色敛嫣红。</strong></p></li><li><p><strong>愿清欢长伴，凛冬有暖；愿岁岁平安，流光静看，愿眸光淡然，烟火无干。</strong></p></li><li><p><strong>江南的春风没能吹到塞北，塞北的飞蓬也未能飘至江南，你我没有江南塞北的距离，为何有着江南塞北的结局。</strong></p></li><li><p><strong>属于我的那缕月光，是否轻落你衣裳。</strong></p></li><li><p><strong>如果流年，也懂离伤。</strong></p></li><li><p><strong>不似桃李，何同芳尘，只若江上清风，山间明月，又如霜雪初降，寒溪兀流。自脱胎于冰雪，何沾染于凡尘？</strong></p></li><li><p><strong>我既生而自由，世间何来枷锁。</strong></p></li><li><p><strong>我很想你，一想起你便想喝酒了。只怪清醒时不敢想你，醉了便能少些顾忌。</strong></p></li><li><p><strong>远方的酒，无端唤起故乡的愁，故乡的梦，何故吹着远方的风。</strong></p></li><li><p><strong>掌纹如果预示着命运，我们双手紧握的那一刻，命运也该有不可分割的交集吧</strong></p></li></ul>]]></content>
      
      
      <categories>
          
          <category> 创作 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> 写作 </tag>
            
            <tag> 文案 </tag>
            
            <tag> 文学 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>在花丛里躺好的书卷（作者送给朋友的诗）</title>
      <link href="/2025/09/22/%E8%BA%BA%E5%9C%A8%E8%8A%B1%E4%B8%9B%E4%B8%AD%E7%9A%84%E4%B9%A6%E5%8D%B7/"/>
      <url>/2025/09/22/%E8%BA%BA%E5%9C%A8%E8%8A%B1%E4%B8%9B%E4%B8%AD%E7%9A%84%E4%B9%A6%E5%8D%B7/</url>
      
        <content type="html"><![CDATA[        <h2 id="醉花阴"   >          <a href="#醉花阴" class="heading-link"><i class="fas fa-link"></i></a><a href="#醉花阴" class="headerlink" title="醉花阴"></a>醉花阴</h2>      <p>松生崔嵬月华清，林深成双行。狸奴知意，南风岑临，晓光初破云。<br>莫道情意酒中轻，初识知盖倾。纵化东海浪，但持恣意，身如青童君。</p>        <h2 id="卜算子"   >          <a href="#卜算子" class="heading-link"><i class="fas fa-link"></i></a><a href="#卜算子" class="headerlink" title="卜算子"></a>卜算子</h2>      <p>期年白驹间，识君如长夏。黛眉何须张敞画，灼灼自风华。<br>南岳齐浮云，湘灵瑟生花。扶余天寒心何住，故人亦故家。</p>        <h2 id="虞美人"   >          <a href="#虞美人" class="heading-link"><i class="fas fa-link"></i></a><a href="#虞美人" class="headerlink" title="虞美人"></a>虞美人</h2>      <p>菡萏香销朔风寒，碎琼素色染。青山一夜华发，却称天公兴高艺超然。<br>纵是巧工无青睐，缘卿胜佳景，感君桃潭赠物情，愿得皓月清光长顾伊。</p>        <h2 id="赠友-前途似海"   >          <a href="#赠友-前途似海" class="heading-link"><i class="fas fa-link"></i></a><a href="#赠友-前途似海" class="headerlink" title="赠友-前途似海"></a>赠友-前途似海</h2>      <p>前路，山海遥遥，风月正好。<br>途中，却霜雪满山，骤雨拦道。<br>似水流年，还总于俗世奔劳<br>海水无际，泛舟苦苦寻觅。</p><p>来往的人很多，也仅仅是多。<br>日光侵蚀着年少的心，<br>方饮下一瓢酒，便在心中酿作了愁。<br>长风破浪，成了再难挥去的忧。</p>        <h2 id="醉花阴-1"   >          <a href="#醉花阴-1" class="heading-link"><i class="fas fa-link"></i></a><a href="#醉花阴-1" class="headerlink" title="醉花阴"></a>醉花阴</h2>      <p>莫道未逢晓雾遮，共闻湘灵瑟。洞庭浩汤，黄鹄振翅，风渡云梦泽。<br>吹梦扶余肃景澈，初历天寒彻。细数碎琼，难凉热血，振衣瀚海辙。</p>        <h2 id="自度曲"   >          <a href="#自度曲" class="heading-link"><i class="fas fa-link"></i></a><a href="#自度曲" class="headerlink" title="自度曲"></a>自度曲</h2>      <p>瑶台月下，雾失流云。道是云汉明浠水，却将凡尘寻。<br>不染俗华，山花盈盈。待到清啼散晨雾，（）</p><blockquote><p>末句怎么也回忆不起来了，遗憾总是难免的。也许你还会保存下来当年我送你的词吧，也许我可以补全它，但也没意义了，就像我们哪怕重来一次 也没意义了。有些事总会被遗忘的，这次是词，下次是我们哪一段过去。</p></blockquote>        <h2 id="苏幕遮"   >          <a href="#苏幕遮" class="heading-link"><i class="fas fa-link"></i></a><a href="#苏幕遮" class="headerlink" title="苏幕遮"></a>苏幕遮</h2>      <p>梧桐木，起闲愁，相思难晚，山远几重秋，霜寒柳烟雾笼舟，何处归渡，天高雁引忧。</p><p>道千阻，君安否，西风临江，遥恐沈瑶瘦。长望月明云气收，清光愿落，故人所行游。</p>]]></content>
      
      
      <categories>
          
          <category> 创作 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> 写作 </tag>
            
            <tag> 文案 </tag>
            
            <tag> 文学 </tag>
            
            <tag> 诗词 </tag>
            
            <tag> 友情 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>遗落在山间的诗稿（作者写的古体诗）</title>
      <link href="/2025/09/22/%E9%81%97%E8%90%BD%E5%9C%A8%E5%B1%B1%E9%97%B4%E7%9A%84%E8%AF%97%E7%A8%BF/"/>
      <url>/2025/09/22/%E9%81%97%E8%90%BD%E5%9C%A8%E5%B1%B1%E9%97%B4%E7%9A%84%E8%AF%97%E7%A8%BF/</url>
      
        <content type="html"><![CDATA[<p>整理这些诗文的时候，许多已经想不起了。不记得自己写了哪些诗，在各种可能留下痕迹的地方找了又找。在记忆这座深山里行走时，总免不了迷失。这些诗文的时间跨度很大，有五六年前的，也有近日的。有些写的水平一般的，本不愿放上来。但是细想一番，何必否定自己的过去呢？</p>        <h2 id="凤栖梧"   >          <a href="#凤栖梧" class="heading-link"><i class="fas fa-link"></i></a><a href="#凤栖梧" class="headerlink" title="凤栖梧"></a><strong>凤栖梧</strong></h2>      <p>渐寒冬木纷华收，<u>远望梨花，冰枝琉璃透</u>。却道行人多回首，灵清不同桃李柔。<br>流云飞散覆兰舟，仙卿踏雪，衣袂舞冷骤。应有玉人立江洲，梅魂冰骨渐白头。</p><img src="/images/950218a93160439623a2fa78182bd16.jpg" alt="950218a93160439623a2fa78182bd16" style="zoom: 33%;" /><blockquote><p>高中那年见证了人生第一次冻雨，晚自习回家的路上看到这一幕，为之震撼，故记之。</p></blockquote>        <h2 id="自度曲"   >          <a href="#自度曲" class="heading-link"><i class="fas fa-link"></i></a><a href="#自度曲" class="headerlink" title="自度曲"></a>自度曲</h2>      <p>水天一色，原是日已晚，泪眼潸然。北国方归，何道碎琼寒。忽闻故人，一夜风霜尽染。<br>洞庭无波，昔年<u>梧桐残</u>，湘灵瑟断。杨柳难留，但恨流光晚。云结愁凝，却嗔江风难散。</p><img src="/images/bc2b582dc134ee65bf0c09cbaa5238b.jpg" alt="bc2b582dc134ee65bf0c09cbaa5238b" style="zoom: 33%;" /><blockquote><p>图：高中校园前的梧桐树。</p></blockquote><blockquote><p>2025年一月寒假，洞庭湖边，噙着泪为某位故人写下。</p></blockquote>        <h2 id="苏幕遮"   >          <a href="#苏幕遮" class="heading-link"><i class="fas fa-link"></i></a><a href="#苏幕遮" class="headerlink" title="苏幕遮"></a>苏幕遮</h2>      <p>留行迹，许白首，长情最是，朔时风游。云散广寒轻染月，何携旅思？霜满心头。<br>絮北往，愁南休，离乡何苦，莫怨杨柳。此间入眼空素色，不度江南，送梦岳州。</p><img src="/images/534c57b8ee997243a9f47904344cbf2.jpg" alt="534c57b8ee997243a9f47904344cbf2" style="zoom:33%;" /><blockquote><p>为东北漫天风雪震撼，挑战不着雪字写雪。写着写着想家了。</p></blockquote>        <h2 id="随笔"   >          <a href="#随笔" class="heading-link"><i class="fas fa-link"></i></a><a href="#随笔" class="headerlink" title="随笔"></a>随笔</h2>      <p>白日行云抛妄念，<br>昨夜明月又梦君。<br>倾杯非为琼浆醉，<br>暗托心事与酒听。</p>        <h2 id="虞美人"   >          <a href="#虞美人" class="heading-link"><i class="fas fa-link"></i></a><a href="#虞美人" class="headerlink" title="虞美人"></a>虞美人</h2>      <p>何以再寻玉龙芒，消磨还神伤，诗酒已任韶光弃，江楼无月、东篱无酒觞。<br>年少却异少年样，莫道无惆怅。潘鬓未顾先宋悲，饮甚流霞、宁醉中山长。</p>        <h2 id="游洞庭"   >          <a href="#游洞庭" class="heading-link"><i class="fas fa-link"></i></a><a href="#游洞庭" class="headerlink" title="游洞庭"></a>游洞庭</h2>      <p>闲循古人迹，洞庭衍长空。<br>潮起扬风柳，波皱引兰舟。<br>湘灵瑟不绝，仙人三醉楼。<br>太阿乘曦日，凌空直断流。<br>朝圣自此始，神光通瀛洲。<br>洞庭八百里，诗传三千首。<br>万古悲欢叹，一纸竟足留。<br>李杜存迹此，温如曾醉游。<br>屈子伤木叶，范公论乐忧。<br>遥追古人思，亦共先圣愁。</p><img src="/images/8faa2f8364cbfe114f02af6e77f151c.jpg" alt="8faa2f8364cbfe114f02af6e77f151c" style="zoom:33%;" /><blockquote><p>高中拍的，我最爱的洞庭湖的落日</p></blockquote>        <h2 id="随笔-1"   >          <a href="#随笔-1" class="heading-link"><i class="fas fa-link"></i></a><a href="#随笔-1" class="headerlink" title="随笔"></a>随笔</h2>      <p>无风水天同，云霞敛湖中。<br>枯枝远何似，银汉缀晴空。</p>        <h2 id="念奴娇•记巴陵初雪"   >          <a href="#念奴娇•记巴陵初雪" class="heading-link"><i class="fas fa-link"></i></a><a href="#念奴娇•记巴陵初雪" class="headerlink" title="念奴娇•记巴陵初雪"></a>念奴娇•记巴陵初雪</h2>      <p>南国初雪，正潇潇，素色尽目遥遥。皆道江南和春住，最喜碎琼霁晓。红墙青瓦，流云此散，恍然古今淆。愿得年年，看取傲梅凌霜。<br>晨起总赖冬寒，半晌贪欢，凝雨留人踪。沐雪莫携撑花去，白头愿、几能成。梧桐尚红，满地北风，相思终难寄。洞庭雾渺，湘灵瑟几重。</p><blockquote><p>高三那年冬天，破天荒的下了雪</p></blockquote>        <h2 id="除夕作"   >          <a href="#除夕作" class="heading-link"><i class="fas fa-link"></i></a><a href="#除夕作" class="headerlink" title="除夕作"></a>除夕作</h2>      <p>言是年年复，逝水岁又除。<br>此心常如旧，淡看雪有无。</p>        <h2 id="瞎改"   >          <a href="#瞎改" class="heading-link"><i class="fas fa-link"></i></a><a href="#瞎改" class="headerlink" title="瞎改"></a>瞎改</h2>      <p>冬日游，碎琼落满头。雪上谁家娘子，足风流。妾拟将身嫁与，一生休。纵被无情弃，不能羞。</p>        <h2 id="望江南"   >          <a href="#望江南" class="heading-link"><i class="fas fa-link"></i></a><a href="#望江南" class="headerlink" title="望江南"></a>望江南</h2>      <p>少年好，春光莫虚耗。不见长江水浩浩，奔至东海不复回，风流还觅谁。<br>月光映，离人思清影。莫饮离恨对明月，且换美酒舍金银，执樽对月饮。</p>        <h2 id="孤句"   >          <a href="#孤句" class="heading-link"><i class="fas fa-link"></i></a><a href="#孤句" class="headerlink" title="孤句"></a>孤句</h2>      <p>若远金门亦无悔，权当天意尘明珠。</p>        <h2 id="秋夜观洞庭"   >          <a href="#秋夜观洞庭" class="heading-link"><i class="fas fa-link"></i></a><a href="#秋夜观洞庭" class="headerlink" title="秋夜观洞庭"></a>秋夜观洞庭</h2>      <p>看得荷败料水寒，湖畔凭栏山河晚。<br>今夜星月羞藏帐，晚幕空然心微憾。<br>应是湘神貌绰约，竟愧冰轮惭银汉。<br>最怜月华弃江波，星光不顾少妆淡。<br>秋风暗拭镜如水，渔火悄燃夜无声。<br>夜色隐却行人迹，明暗恍惚现船纹。<br>一时淆望天湖边，欲寻界隔却无际。<br>幻思乘舟至湖尽，桂魄星辰可藏其？<br>温如清梦许堪寻，子美孤舟或此遗。<br>惟愿撑蒿泛洞庭，不羡古人登临意。</p>        <h2 id="无题"   >          <a href="#无题" class="heading-link"><i class="fas fa-link"></i></a><a href="#无题" class="headerlink" title="无题"></a>无题</h2>      <p>南国秋已晚，何处春意生。依依若柳姿，灼灼绝芳尘。</p><p>北国夏荷举，何处闲凉存。皎皎云中月，悠悠空林深。</p>]]></content>
      
      
      <categories>
          
          <category> 创作 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> 写作 </tag>
            
            <tag> 古诗 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>爬虫理论入门</title>
      <link href="/2025/09/19/%E7%88%AC%E8%99%AB%E5%AE%9E%E8%B7%B5/"/>
      <url>/2025/09/19/%E7%88%AC%E8%99%AB%E5%AE%9E%E8%B7%B5/</url>
      
        <content type="html"><![CDATA[        <h3 id="1-如果你不伪装，你会被服务器嘲讽"   >          <a href="#1-如果你不伪装，你会被服务器嘲讽" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-如果你不伪装，你会被服务器嘲讽" class="headerlink" title="1.如果你不伪装，你会被服务器嘲讽"></a>1.如果你不伪装，你会被服务器嘲讽</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"></span><br><span class="line">response=requests.get(<span class="string">&quot;https://movie.douban.com/top250&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(response)</span><br></pre></td></tr></table></div></figure><p>如果你想这样简单的实现爬虫，服务器会告诉你</p><p><strong>&lt;Response [418]&gt;</strong></p><p>状态码 418 实际上是一个愚人节玩笑。它在 RFC 2324 中定义，该 RFC 是一个关于超文本咖啡壶控制协议（HTCPCP）的笑话文件。在这个笑话中，418 状态码是作为一个玩笑加入到 HTTP 协议中的。</p><p><strong>翻译成人话是“你是傻子吗？”</strong></p>        <h3 id="2-如何不被嘲讽"   >          <a href="#2-如何不被嘲讽" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-如何不被嘲讽" class="headerlink" title="2.如何不被嘲讽"></a>2.如何不被嘲讽</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"></span><br><span class="line">headers = &#123;</span><br><span class="line">    <span class="string">&quot;User-Agent&quot;</span>:<span class="string">&quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0&quot;</span></span><br><span class="line">&#125;</span><br><span class="line">response=requests.get(<span class="string">&quot;https://movie.douban.com/top250&quot;</span>,headers=headers)</span><br><span class="line"><span class="built_in">print</span>(response)</span><br></pre></td></tr></table></div></figure><p>那就是headers伪装成正常客户端的访问。得到方法非常简单，f12无需多言</p><p>此时就会显示</p><p>&lt;Response [200]&gt;</p><p>代表你成功了。</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">print(response.text)</span><br></pre></td></tr></table></div></figure><p>这样你就可以得到页面源码了</p>        <h3 id="3-关于request库（一切的基础）"   >          <a href="#3-关于request库（一切的基础）" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-关于request库（一切的基础）" class="headerlink" title="3.关于request库（一切的基础）"></a>3.关于request库（一切的基础）</h3>      <p>上面的代码只是冰山一角，如果要真的全面学习，还是要把基础打牢。</p><p>这是一个常用的HTTP请求库，可以方便的向网站发送请求，也是爬虫技术的基石。</p><p>每次调用request请求之后，会返回一个response对象，该对象包含了具体的响应信息。</p><p>以下列举了部分常用响应信息的属性方法使用。</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#import request</span></span><br><span class="line"></span><br><span class="line">url=<span class="string">&#x27;你要发送请求的网址&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#发送请求</span></span><br><span class="line">x=request.get(url)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(x.text)<span class="comment">#返回网页内容</span></span><br><span class="line"><span class="built_in">print</span>(x.status_code)<span class="comment">#返回http状态码</span></span><br><span class="line"><span class="built_in">print</span>(x.reason)<span class="comment">#响应状态的描述，比如ok</span></span><br><span class="line"><span class="built_in">print</span>(x.apparent_encoding)<span class="comment">#返回编码 比如 utf-8</span></span><br><span class="line"><span class="built_in">print</span>(x.json)<span class="comment">#返回json数据</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="string">&#123;&#x27;name&#x27;: &#x27;网站&#x27;, &#x27;num&#x27;: 3, &#x27;sites&#x27;: [&#123;&#x27;name&#x27;: &#x27;Google&#x27;, &#x27;info&#x27;: [&#x27;Android&#x27;, &#x27;Google 搜索&#x27;, &#x27;Google 翻译&#x27;]&#125;, &#123;&#x27;name&#x27;: &#x27;Runoob&#x27;, &#x27;info&#x27;: [&#x27;菜鸟教程&#x27;, &#x27;菜鸟工具&#x27;, &#x27;菜鸟微信&#x27;]&#125;, &#123;&#x27;name&#x27;: &#x27;Taobao&#x27;, &#x27;info&#x27;: [&#x27;淘宝&#x27;, &#x27;网购&#x27;]&#125;]&#125;</span></span><br><span class="line"><span class="string">&#x27;&#x27;&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(x.cookies)<span class="comment">#返回CookieJar对象，包含从服务器发送的cookie</span></span><br><span class="line"><span class="built_in">print</span>(x.headers)<span class="comment">#返回响应头</span></span><br></pre></td></tr></table></div></figure><p>以下是request方法</p><div class="table-container"><table><thead><tr><th>方法</th><th>描述</th></tr></thead><tbody><tr><td>delete(url,args)</td><td>发送delete请求到指定url</td></tr><tr><td>get(url,params,args)</td><td>发送GET请求到指定url</td></tr><tr><td>head(url,args)</td><td>发送HEAD请求到指定url</td></tr><tr><td>patch(url,data,args)</td><td>发送PATCH请求到指定url</td></tr><tr><td>post(url,data,json,args)</td><td>发送POST请求到指定url</td></tr><tr><td>put(url,data,args)</td><td>发送PUT请求到指定url</td></tr><tr><td>request(<em>method</em>, <em>url</em>, <em>args</em>)</td><td>向指定的 url 发送指定的请求方法</td></tr></tbody></table></div><p><strong>get和request</strong></p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#import requests</span></span><br><span class="line"></span><br><span class="line">kw=&#123;<span class="string">&#x27;s&#x27;</span>:<span class="string">&#x27;python教程&#x27;</span>&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">#设置请求头</span></span><br><span class="line">headers=&#123;&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">#params接受一个字典或字符串的查询参数，字典类型自动转化为url编码</span></span><br><span class="line">response=requests.get(<span class="string">&quot;url&quot;</span>,params=kw,headers=headers)</span><br><span class="line"><span class="comment">#request的使用</span></span><br><span class="line">x=requests.request(<span class="string">&#x27;get&#x27;</span>,<span class="string">&#x27;url&#x27;</span>)</span><br></pre></td></tr></table></div></figure><p><strong>post</strong></p><p>post() 方法可以发送 POST 请求到指定 url，一般格式如下：</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">requests.post(url, data=&#123;key: value&#125;, json=&#123;key: value&#125;, args)</span><br></pre></td></tr></table></div></figure><ul><li><strong>url</strong> 请求 url。</li><li><strong>data</strong> 参数为要发送到指定 url 的字典、元组列表、字节或文件对象。</li><li><strong>json</strong> 参数为要发送到指定 url 的 JSON 对象。</li><li><strong>args</strong> 为其他参数，比如 cookies、headers、verify等</li></ul><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 导入 requests 包</span></span><br><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"></span><br><span class="line"><span class="comment"># 表单参数，参数名为 fname 和 lname</span></span><br><span class="line">myobj = &#123;<span class="string">&#x27;fname&#x27;</span>: <span class="string">&#x27;RUNOOB&#x27;</span>,<span class="string">&#x27;lname&#x27;</span>: <span class="string">&#x27;Boy&#x27;</span>&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment"># 发送请求</span></span><br><span class="line">x = requests.post(<span class="string">&#x27;https://www.runoob.com/try/ajax/demo_post2.php&#x27;</span>, data = myobj)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 返回网页内容</span></span><br><span class="line"><span class="built_in">print</span>(x.text)</span><br></pre></td></tr></table></div></figure><p><strong>附加请求参数</strong></p><p>发送请求我们可以在请求中附加额外的参数，例如请求头、查询参数、请求体等，例如：</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">headers = &#123;&#x27;User-Agent&#x27;: &#x27;Mozilla/5.0&#x27;&#125;  # 设置请求头</span><br><span class="line">params = &#123;&#x27;key1&#x27;: &#x27;value1&#x27;, &#x27;key2&#x27;: &#x27;value2&#x27;&#125;  # 设置查询参数,params用于在URL后面添加查询字符串(query string)，通常用于GET请求</span><br><span class="line">data = &#123;&#x27;username&#x27;: &#x27;example&#x27;, &#x27;password&#x27;: &#x27;123456&#x27;&#125;  # 设置请求体,data用于发送表单数据，通常用于POST请求。</span><br><span class="line">response = requests.post(&#x27;https://www.runoob.com&#x27;, headers=headers, params=params, data=data)</span><br></pre></td></tr></table></div></figure><p>params和data的示例调用</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"></span><br><span class="line"><span class="comment"># 获取天气信息</span></span><br><span class="line">base_url = <span class="string">&#x27;https://api.weather.com/v3&#x27;</span></span><br><span class="line">params = &#123;</span><br><span class="line">    <span class="string">&#x27;location&#x27;</span>: <span class="string">&#x27;beijing&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;apikey&#x27;</span>: <span class="string">&#x27;your_api_key&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;units&#x27;</span>: <span class="string">&#x27;metric&#x27;</span></span><br><span class="line">&#125;</span><br><span class="line">data = &#123;</span><br><span class="line">    <span class="string">&#x27;fields&#x27;</span>: <span class="string">&#x27;temperature,humidity,windSpeed&#x27;</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">response = requests.post(<span class="string">f&quot;<span class="subst">&#123;base_url&#125;</span>/weather/now&quot;</span>, params=params, json=data)</span><br><span class="line">weather_data = response.json()</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&quot;当前温度: <span class="subst">&#123;weather_data[<span class="string">&#x27;temperature&#x27;</span>]&#125;</span>℃&quot;</span>)</span><br></pre></td></tr></table></div></figure>        <h3 id="4-如何解析得到的信息？BeautifulSoup库"   >          <a href="#4-如何解析得到的信息？BeautifulSoup库" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-如何解析得到的信息？BeautifulSoup库" class="headerlink" title="4.如何解析得到的信息？BeautifulSoup库"></a>4.如何解析得到的信息？BeautifulSoup库</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> bs4 <span class="keyword">import</span> BeautifulSoup</span><br></pre></td></tr></table></div></figure><p>导入这个库之后，就可以开始使用了。</p><p>下面的一段HTML代码将作为例子被多次用到.这是 <em>爱丽丝梦游仙境的</em> 的一段内容(以后内容中简称为 <em>爱丽丝</em> 的文档):</p><figure class="highlight html"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">html_doc = &quot;&quot;&quot;</span><br><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span><span class="tag">&lt;<span class="name">head</span>&gt;</span><span class="tag">&lt;<span class="name">title</span>&gt;</span>The Dormouse&#x27;s story<span class="tag">&lt;/<span class="name">title</span>&gt;</span><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">p</span> <span class="attr">class</span>=<span class="string">&quot;title&quot;</span>&gt;</span><span class="tag">&lt;<span class="name">b</span>&gt;</span>The Dormouse&#x27;s story<span class="tag">&lt;/<span class="name">b</span>&gt;</span><span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">p</span> <span class="attr">class</span>=<span class="string">&quot;story&quot;</span>&gt;</span>Once upon a time there were three little sisters; and their names were</span><br><span class="line"><span class="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">&quot;http://example.com/elsie&quot;</span> <span class="attr">class</span>=<span class="string">&quot;sister&quot;</span> <span class="attr">id</span>=<span class="string">&quot;link1&quot;</span>&gt;</span>Elsie<span class="tag">&lt;/<span class="name">a</span>&gt;</span>,</span><br><span class="line"><span class="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">&quot;http://example.com/lacie&quot;</span> <span class="attr">class</span>=<span class="string">&quot;sister&quot;</span> <span class="attr">id</span>=<span class="string">&quot;link2&quot;</span>&gt;</span>Lacie<span class="tag">&lt;/<span class="name">a</span>&gt;</span> and</span><br><span class="line"><span class="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">&quot;http://example.com/tillie&quot;</span> <span class="attr">class</span>=<span class="string">&quot;sister&quot;</span> <span class="attr">id</span>=<span class="string">&quot;link3&quot;</span>&gt;</span>Tillie<span class="tag">&lt;/<span class="name">a</span>&gt;</span>;</span><br><span class="line">and they lived at the bottom of a well.<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">p</span> <span class="attr">class</span>=<span class="string">&quot;story&quot;</span>&gt;</span>...<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">&quot;&quot;&quot;</span><br></pre></td></tr></table></div></figure><p>使用BeautifulSoup解析这段代码,能够得到一个 <code>BeautifulSoup</code> 的对象,并能按照标准的缩进格式的结构输出:</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> bs4 <span class="keyword">import</span> BeautifulSoup</span><br><span class="line">soup = BeautifulSoup(html_doc, <span class="string">&#x27;html.parser&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(soup.prettify())</span><br><span class="line"><span class="comment"># &lt;html&gt;</span></span><br><span class="line"><span class="comment">#  &lt;head&gt;</span></span><br><span class="line"><span class="comment">#   &lt;title&gt;</span></span><br><span class="line"><span class="comment">#    The Dormouse&#x27;s story</span></span><br><span class="line"><span class="comment">#   &lt;/title&gt;</span></span><br><span class="line"><span class="comment">#  &lt;/head&gt;</span></span><br><span class="line"><span class="comment">#  &lt;body&gt;</span></span><br><span class="line"><span class="comment">#   &lt;p class=&quot;title&quot;&gt;</span></span><br><span class="line"><span class="comment">#    &lt;b&gt;</span></span><br><span class="line"><span class="comment">#     The Dormouse&#x27;s story</span></span><br><span class="line"><span class="comment">#    &lt;/b&gt;</span></span><br><span class="line"><span class="comment">#   &lt;/p&gt;</span></span><br><span class="line"><span class="comment">#   &lt;p class=&quot;story&quot;&gt;</span></span><br><span class="line"><span class="comment">#    Once upon a time there were three little sisters; and their names were</span></span><br><span class="line"><span class="comment">#    &lt;a class=&quot;sister&quot; href=&quot;http://example.com/elsie&quot; id=&quot;link1&quot;&gt;</span></span><br><span class="line"><span class="comment">#     Elsie</span></span><br><span class="line"><span class="comment">#    &lt;/a&gt;</span></span><br><span class="line"><span class="comment">#    ,</span></span><br><span class="line"><span class="comment">#    &lt;a class=&quot;sister&quot; href=&quot;http://example.com/lacie&quot; id=&quot;link2&quot;&gt;</span></span><br><span class="line"><span class="comment">#     Lacie</span></span><br><span class="line"><span class="comment">#    &lt;/a&gt;</span></span><br><span class="line"><span class="comment">#    and</span></span><br><span class="line"><span class="comment">#    &lt;a class=&quot;sister&quot; href=&quot;http://example.com/tillie&quot; id=&quot;link2&quot;&gt;</span></span><br><span class="line"><span class="comment">#     Tillie</span></span><br><span class="line"><span class="comment">#    &lt;/a&gt;</span></span><br><span class="line"><span class="comment">#    ; and they lived at the bottom of a well.</span></span><br><span class="line"><span class="comment">#   &lt;/p&gt;</span></span><br><span class="line"><span class="comment">#   &lt;p class=&quot;story&quot;&gt;</span></span><br><span class="line"><span class="comment">#    ...</span></span><br><span class="line"><span class="comment">#   &lt;/p&gt;</span></span><br><span class="line"><span class="comment">#  &lt;/body&gt;</span></span><br><span class="line"><span class="comment"># &lt;/html&gt;</span></span><br></pre></td></tr></table></div></figure><p>几个简单的浏览结构化数据的方法:</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">soup.title</span><br><span class="line"><span class="comment"># &lt;title&gt;The Dormouse&#x27;s story&lt;/title&gt;</span></span><br><span class="line"></span><br><span class="line">soup.title.name</span><br><span class="line"><span class="comment"># u&#x27;title&#x27;</span></span><br><span class="line"></span><br><span class="line">soup.title.string</span><br><span class="line"><span class="comment"># u&#x27;The Dormouse&#x27;s story&#x27;</span></span><br><span class="line"></span><br><span class="line">soup.title.parent.name</span><br><span class="line"><span class="comment"># u&#x27;head&#x27;</span></span><br><span class="line"></span><br><span class="line">soup.p</span><br><span class="line"><span class="comment"># &lt;p class=&quot;title&quot;&gt;&lt;b&gt;The Dormouse&#x27;s story&lt;/b&gt;&lt;/p&gt;</span></span><br><span class="line"></span><br><span class="line">soup.p[<span class="string">&#x27;class&#x27;</span>]</span><br><span class="line"><span class="comment"># u&#x27;title&#x27;</span></span><br><span class="line"></span><br><span class="line">soup.a</span><br><span class="line"><span class="comment"># &lt;a class=&quot;sister&quot; href=&quot;http://example.com/elsie&quot; id=&quot;link1&quot;&gt;Elsie&lt;/a&gt;</span></span><br><span class="line"></span><br><span class="line">soup.find_all(<span class="string">&#x27;a&#x27;</span>)</span><br><span class="line"><span class="comment"># [&lt;a class=&quot;sister&quot; href=&quot;http://example.com/elsie&quot; id=&quot;link1&quot;&gt;Elsie&lt;/a&gt;,</span></span><br><span class="line"><span class="comment">#  &lt;a class=&quot;sister&quot; href=&quot;http://example.com/lacie&quot; id=&quot;link2&quot;&gt;Lacie&lt;/a&gt;,</span></span><br><span class="line"><span class="comment">#  &lt;a class=&quot;sister&quot; href=&quot;http://example.com/tillie&quot; id=&quot;link3&quot;&gt;Tillie&lt;/a&gt;]</span></span><br><span class="line"></span><br><span class="line">soup.find(<span class="built_in">id</span>=<span class="string">&quot;link3&quot;</span>)</span><br><span class="line"><span class="comment"># &lt;a class=&quot;sister&quot; href=&quot;http://example.com/tillie&quot; id=&quot;link3&quot;&gt;Tillie&lt;/a&gt;</span></span><br></pre></td></tr></table></div></figure><p>从文档中找到所有<a>标签的链接:</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> link <span class="keyword">in</span> soup.find_all(<span class="string">&#x27;a&#x27;</span>):</span><br><span class="line">    <span class="built_in">print</span>(link.get(<span class="string">&#x27;href&#x27;</span>))</span><br><span class="line">    <span class="comment"># http://example.com/elsie</span></span><br><span class="line">    <span class="comment"># http://example.com/lacie</span></span><br><span class="line">    <span class="comment"># http://example.com/tillie</span></span><br></pre></td></tr></table></div></figure><p>从文档中获取所有文字内容:</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">print</span>(soup.get_text())</span><br><span class="line"><span class="comment"># The Dormouse&#x27;s story</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># The Dormouse&#x27;s story</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Once upon a time there were three little sisters; and their names were</span></span><br><span class="line"><span class="comment"># Elsie,</span></span><br><span class="line"><span class="comment"># Lacie and</span></span><br><span class="line"><span class="comment"># Tillie;</span></span><br><span class="line"><span class="comment"># and they lived at the bottom of a well.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># ...</span></span><br></pre></td></tr></table></div></figure>        <h3 id="5-尝试汇总我们学到的知识"   >          <a href="#5-尝试汇总我们学到的知识" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-尝试汇总我们学到的知识" class="headerlink" title="5.尝试汇总我们学到的知识"></a>5.尝试汇总我们学到的知识</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#如何获取网页标题</span></span><br><span class="line"><span class="keyword">from</span> bs4 <span class="keyword">import</span> BeautifulSoup</span><br><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"></span><br><span class="line">url=<span class="string">&#x27;x&#x27;</span></span><br><span class="line">response=requests.get(url)</span><br><span class="line"><span class="comment">#解决中文乱码问题</span></span><br><span class="line">response.encoding=<span class="string">&#x27;utf-8&#x27;</span></span><br><span class="line"><span class="comment">#确保请求成功</span></span><br><span class="line"><span class="keyword">if</span> response.status_code==<span class="number">200</span>:</span><br><span class="line">    soup=BeautifulSoup(response.text,<span class="string">&#x27;html.parser&#x27;</span>)</span><br><span class="line">     <span class="comment">#查找&lt;title&gt;标签</span></span><br><span class="line">     title_tag=soup.find(<span class="string">&#x27;title&#x27;</span>)</span><br><span class="line">     <span class="comment"># 打印标题文本</span></span><br><span class="line">    <span class="keyword">if</span> title_tag:</span><br><span class="line">        <span class="built_in">print</span>(title_tag.get_text())</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;未找到&lt;title&gt;标签&quot;</span>)</span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;请求失败，状态码：&quot;</span>, response.status_code)</span><br></pre></td></tr></table></div></figure><p>find和find_all方法的使用</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> bs4 <span class="keyword">import</span> BeautifulSoup</span><br><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"></span><br><span class="line"><span class="comment"># 指定你想要获取标题的网站</span></span><br><span class="line">url = <span class="string">&#x27;https://www.baidu.com/&#x27;</span> <span class="comment"># 抓取bing搜索引擎的网页内容</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 发送HTTP请求获取网页内容</span></span><br><span class="line">response = requests.get(url)</span><br><span class="line"><span class="comment"># 中文乱码问题</span></span><br><span class="line">response.encoding = <span class="string">&#x27;utf-8&#x27;</span></span><br><span class="line"></span><br><span class="line">soup = BeautifulSoup(response.text, <span class="string">&#x27;lxml&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查找第一个 &lt;a&gt; 标签</span></span><br><span class="line">first_link = soup.find(<span class="string">&#x27;a&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(first_link)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;----------------------------&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 获取第一个 &lt;a&gt; 标签的 href 属性</span></span><br><span class="line">first_link_url = first_link.get(<span class="string">&#x27;href&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(first_link_url)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;----------------------------&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查找所有 &lt;a&gt; 标签</span></span><br><span class="line">all_links = soup.find_all(<span class="string">&#x27;a&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(all_links)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查找具有 id=&quot;unique-id&quot; 的 &lt;input&gt; 标签</span></span><br><span class="line">unique_input = soup.find(<span class="string">&#x27;input&#x27;</span>, <span class="built_in">id</span>=<span class="string">&#x27;su&#x27;</span>)</span><br><span class="line"></span><br><span class="line">input_value = unique_input[<span class="string">&#x27;value&#x27;</span>] <span class="comment"># 获取 input 输入框的值</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(input_value)</span><br></pre></td></tr></table></div></figure>]]></content>
      
      
      <categories>
          
          <category> 爬虫 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> python </tag>
            
            <tag> 爬虫 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>类和对象</title>
      <link href="/2025/09/13/%E7%B1%BB%E5%92%8C%E5%AF%B9%E8%B1%A1/"/>
      <url>/2025/09/13/%E7%B1%BB%E5%92%8C%E5%AF%B9%E8%B1%A1/</url>
      
        <content type="html"><![CDATA[        <h2 id="一、继承的基本概念"   >          <a href="#一、继承的基本概念" class="heading-link"><i class="fas fa-link"></i></a><a href="#一、继承的基本概念" class="headerlink" title="一、继承的基本概念"></a>一、继承的基本概念</h2>      <p>继承是面向对象编程的三大特性之一（封装、继承、多态），它允许我们定义一个类（子类）来继承另一个类（父类）的属性和方法。</p>        <h3 id="1-基本语法"   >          <a href="#1-基本语法" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-基本语法" class="headerlink" title="1. 基本语法"></a>1. 基本语法</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">ParentClass</span>:</span><br><span class="line">    <span class="string">&quot;&quot;&quot;父类/基类&quot;&quot;&quot;</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">parent_method</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;这是父类方法&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">ChildClass</span>(<span class="title class_ inherited__">ParentClass</span>):</span><br><span class="line">    <span class="string">&quot;&quot;&quot;子类/派生类&quot;&quot;&quot;</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">child_method</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;这是子类方法&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用示例</span></span><br><span class="line">child = ChildClass()</span><br><span class="line">child.parent_method()  <span class="comment"># 调用继承的方法</span></span><br><span class="line">child.child_method()   <span class="comment"># 调用子类自己的方法</span></span><br></pre></td></tr></table></div></figure>        <h3 id="2-继承的特性"   >          <a href="#2-继承的特性" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-继承的特性" class="headerlink" title="2. 继承的特性"></a>2. 继承的特性</h3>      <ul><li>子类继承父类的所有<strong>公有属性和方法</strong></li><li>子类可以<strong>扩展</strong>父类的功能</li><li>子类可以<strong>重写</strong>父类的方法</li><li>子类的实例也是父类的实例（<code>isinstance</code> 返回 <code>True</code>）</li></ul>        <h2 id="二、方法重写（Override）"   >          <a href="#二、方法重写（Override）" class="heading-link"><i class="fas fa-link"></i></a><a href="#二、方法重写（Override）" class="headerlink" title="二、方法重写（Override）"></a>二、方法重写（Override）</h2>      <p>子类可以重新定义父类的方法，这称为方法重写。</p>        <h3 id="1-完全重写"   >          <a href="#1-完全重写" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-完全重写" class="headerlink" title="1. 完全重写"></a>1. 完全重写</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Animal</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">speak</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;动物发出声音&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Dog</span>(<span class="title class_ inherited__">Animal</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">speak</span>(<span class="params">self</span>):  <span class="comment"># 完全重写父类方法</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;汪汪汪！&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用示例</span></span><br><span class="line">dog = Dog()</span><br><span class="line">dog.speak()  <span class="comment"># 输出: 汪汪汪！</span></span><br></pre></td></tr></table></div></figure>        <h3 id="2-扩展父类方法（使用-super-）"   >          <a href="#2-扩展父类方法（使用-super-）" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-扩展父类方法（使用-super-）" class="headerlink" title="2. 扩展父类方法（使用 super()）"></a>2. 扩展父类方法（使用 super()）</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Animal</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, name</span>):</span><br><span class="line">        <span class="variable language_">self</span>.name = name</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Cat</span>(<span class="title class_ inherited__">Animal</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, name, color</span>):</span><br><span class="line">        <span class="built_in">super</span>().__init__(name)  <span class="comment"># 调用父类的初始化方法</span></span><br><span class="line">        <span class="variable language_">self</span>.color = color      <span class="comment"># 添加新的属性</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用示例</span></span><br><span class="line">cat = Cat(<span class="string">&quot;咪咪&quot;</span>, <span class="string">&quot;白色&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&quot;名字: <span class="subst">&#123;cat.name&#125;</span>, 颜色: <span class="subst">&#123;cat.color&#125;</span>&quot;</span>)</span><br></pre></td></tr></table></div></figure>        <h2 id="三、多重继承"   >          <a href="#三、多重继承" class="heading-link"><i class="fas fa-link"></i></a><a href="#三、多重继承" class="headerlink" title="三、多重继承"></a>三、多重继承</h2>      <p>Python 支持多重继承，即一个类可以继承多个父类。</p>        <h3 id="1-基本语法-1"   >          <a href="#1-基本语法-1" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-基本语法-1" class="headerlink" title="1. 基本语法"></a>1. 基本语法</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Father</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">father_method</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;父亲的方法&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Mother</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">mother_method</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;母亲的方法&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Child</span>(Father, Mother):  <span class="comment"># 继承多个父类</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">child_method</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;孩子的方法&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用示例</span></span><br><span class="line">child = Child()</span><br><span class="line">child.father_method()  <span class="comment"># 调用Father的方法</span></span><br><span class="line">child.mother_method()  <span class="comment"># 调用Mother的方法</span></span><br><span class="line">child.child_method()   <span class="comment"># 调用自己的方法</span></span><br></pre></td></tr></table></div></figure>        <h3 id="2-方法解析顺序（MRO）"   >          <a href="#2-方法解析顺序（MRO）" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-方法解析顺序（MRO）" class="headerlink" title="2. 方法解析顺序（MRO）"></a>2. 方法解析顺序（MRO）</h3>      <p>当多个父类有同名方法时，Python 使用 C3 算法确定调用顺序，可以通过 <code>类名.__mro__</code> 查看。</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">A</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">method</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;A的方法&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">B</span>(<span class="title class_ inherited__">A</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">method</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;B的方法&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">C</span>(<span class="title class_ inherited__">A</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">method</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;C的方法&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">D</span>(B, C):</span><br><span class="line">    <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(D.__mro__)  <span class="comment"># 查看方法解析顺序</span></span><br><span class="line"><span class="comment"># 输出: (&lt;class &#x27;__main__.D&#x27;&gt;, &lt;class &#x27;__main__.B&#x27;&gt;, &lt;class &#x27;__main__.C&#x27;&gt;, &lt;class &#x27;__main__.A&#x27;&gt;, &lt;class &#x27;object&#x27;&gt;)</span></span><br><span class="line"></span><br><span class="line">d = D()</span><br><span class="line">d.method()  <span class="comment"># 输出: B的方法</span></span><br></pre></td></tr></table></div></figure>        <h3 id="3-菱形继承问题"   >          <a href="#3-菱形继承问题" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-菱形继承问题" class="headerlink" title="3. 菱形继承问题"></a>3. 菱形继承问题</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">A</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">method</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;A的方法&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">B</span>(<span class="title class_ inherited__">A</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">method</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;B的方法&quot;</span>)</span><br><span class="line">        <span class="built_in">super</span>().method()  <span class="comment"># 调用下一个类的方法</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">C</span>(<span class="title class_ inherited__">A</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">method</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;C的方法&quot;</span>)</span><br><span class="line">        <span class="built_in">super</span>().method()</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">D</span>(B, C):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">method</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;D的方法&quot;</span>)</span><br><span class="line">        <span class="built_in">super</span>().method()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 方法调用顺序: D -&gt; B -&gt; C -&gt; A</span></span><br><span class="line">d = D()</span><br><span class="line">d.method()</span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">输出:</span></span><br><span class="line"><span class="string">D的方法</span></span><br><span class="line"><span class="string">B的方法</span></span><br><span class="line"><span class="string">C的方法</span></span><br><span class="line"><span class="string">A的方法</span></span><br><span class="line"><span class="string">&quot;&quot;&quot;</span></span><br></pre></td></tr></table></div></figure>        <h2 id="四、特殊方法与继承"   >          <a href="#四、特殊方法与继承" class="heading-link"><i class="fas fa-link"></i></a><a href="#四、特殊方法与继承" class="headerlink" title="四、特殊方法与继承"></a>四、特殊方法与继承</h2>              <h3 id="1-init-方法的继承"   >          <a href="#1-init-方法的继承" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-init-方法的继承" class="headerlink" title="1. __init__ 方法的继承"></a>1. <code>__init__</code> 方法的继承</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, name</span>):</span><br><span class="line">        <span class="variable language_">self</span>.name = name</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Student</span>(<span class="title class_ inherited__">Person</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, name, student_id</span>):</span><br><span class="line">        <span class="built_in">super</span>().__init__(name)  <span class="comment"># 调用父类的__init__</span></span><br><span class="line">        <span class="variable language_">self</span>.student_id = student_id</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用示例</span></span><br><span class="line">student = Student(<span class="string">&quot;张三&quot;</span>, <span class="string">&quot;2023001&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(student.name, student.student_id)</span><br></pre></td></tr></table></div></figure>        <h3 id="2-其他特殊方法的重写"   >          <a href="#2-其他特殊方法的重写" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-其他特殊方法的重写" class="headerlink" title="2. 其他特殊方法的重写"></a>2. 其他特殊方法的重写</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">MyList</span>(<span class="title class_ inherited__">list</span>):  <span class="comment"># 继承内置list类</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__str__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="comment"># 重写__str__方法</span></span><br><span class="line">        <span class="keyword">return</span> <span class="string">f&quot;MyList: <span class="subst">&#123;<span class="built_in">super</span>().__str__()&#125;</span>&quot;</span></span><br><span class="line"></span><br><span class="line">lst = MyList([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>])</span><br><span class="line"><span class="built_in">print</span>(lst)  <span class="comment"># 输出: MyList: [1, 2, 3]</span></span><br></pre></td></tr></table></div></figure>        <h2 id="五、抽象基类与接口"   >          <a href="#五、抽象基类与接口" class="heading-link"><i class="fas fa-link"></i></a><a href="#五、抽象基类与接口" class="headerlink" title="五、抽象基类与接口"></a>五、抽象基类与接口</h2>      <p>Python 通过 <code>abc</code> 模块支持抽象基类。</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> abc <span class="keyword">import</span> ABC, abstractmethod</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Shape</span>(<span class="title class_ inherited__">ABC</span>):  <span class="comment"># 抽象基类</span></span><br><span class="line"><span class="meta">    @abstractmethod</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">area</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"><span class="meta">    @abstractmethod</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">perimeter</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Circle</span>(<span class="title class_ inherited__">Shape</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, radius</span>):</span><br><span class="line">        <span class="variable language_">self</span>.radius = radius</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">area</span>(<span class="params">self</span>):  <span class="comment"># 必须实现抽象方法</span></span><br><span class="line">        <span class="keyword">return</span> <span class="number">3.14</span> * <span class="variable language_">self</span>.radius ** <span class="number">2</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">perimeter</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> <span class="number">2</span> * <span class="number">3.14</span> * <span class="variable language_">self</span>.radius</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用示例</span></span><br><span class="line">circle = Circle(<span class="number">5</span>)</span><br><span class="line"><span class="built_in">print</span>(circle.area())  <span class="comment"># 输出: 78.5</span></span><br></pre></td></tr></table></div></figure>        <h2 id="六、继承的最佳实践"   >          <a href="#六、继承的最佳实践" class="heading-link"><i class="fas fa-link"></i></a><a href="#六、继承的最佳实践" class="headerlink" title="六、继承的最佳实践"></a>六、继承的最佳实践</h2>      <ol><li><strong>优先使用组合而非继承</strong>：除非确实是”is-a”关系</li><li><strong>避免深度继承</strong>：继承层次不宜过深</li><li><strong>合理使用多重继承</strong>：谨慎设计，避免复杂关系</li><li><strong>使用抽象基类定义接口</strong>：明确子类需要实现的方法</li><li><strong>遵循LSP原则</strong>：子类应该能够替换父类</li></ol>        <h2 id="七、完整示例"   >          <a href="#七、完整示例" class="heading-link"><i class="fas fa-link"></i></a><a href="#七、完整示例" class="headerlink" title="七、完整示例"></a>七、完整示例</h2>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 多重继承综合示例</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Animal</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, name</span>):</span><br><span class="line">        <span class="variable language_">self</span>.name = name</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">eat</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;self.name&#125;</span>正在吃东西&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Flyable</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">fly</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;self.name&#125;</span>正在飞翔&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Swimable</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">swim</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;self.name&#125;</span>正在游泳&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Bird</span>(Animal, Flyable):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, name</span>):</span><br><span class="line">        <span class="built_in">super</span>().__init__(name)</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">speak</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;self.name&#125;</span>在唱歌&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Duck</span>(Bird, Swimable):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, name</span>):</span><br><span class="line">        <span class="built_in">super</span>().__init__(name)</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">speak</span>(<span class="params">self</span>):  <span class="comment"># 重写父类方法</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;self.name&#125;</span>在嘎嘎叫&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用示例</span></span><br><span class="line">duck = Duck(<span class="string">&quot;唐老鸭&quot;</span>)</span><br><span class="line">duck.eat()    <span class="comment"># 继承自Animal</span></span><br><span class="line">duck.fly()    <span class="comment"># 继承自Flyable</span></span><br><span class="line">duck.swim()   <span class="comment"># 继承自Swimable</span></span><br><span class="line">duck.speak()  <span class="comment"># 调用重写后的方法</span></span><br></pre></td></tr></table></div></figure>]]></content>
      
      
      <categories>
          
          <category> python学习 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> python </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>函数 &amp;&amp; 文件存储 &amp;&amp; 异常</title>
      <link href="/2025/09/10/%E5%87%BD%E6%95%B0/"/>
      <url>/2025/09/10/%E5%87%BD%E6%95%B0/</url>
      
        <content type="html"><![CDATA[        <h3 id="1-如何给函数写注释"   >          <a href="#1-如何给函数写注释" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-如何给函数写注释" class="headerlink" title="1.如何给函数写注释"></a>1.如何给函数写注释</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">a</span>(<span class="params">name</span>):</span><br><span class="line"><span class="string">&#x27;函数文档在函数定义的最开头部分，用不记名字符串表示&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;aa&#x27;</span>)</span><br></pre></td></tr></table></div></figure>        <h3 id="2-关键字参数"   >          <a href="#2-关键字参数" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-关键字参数" class="headerlink" title="2.关键字参数"></a>2.关键字参数</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">a</span>(<span class="params">name,words</span>):</span><br><span class="line"><span class="built_in">print</span>(name + <span class="string">&#x27;-&gt;&#x27;</span>+words)</span><br><span class="line">a(words=<span class="string">&#x27;11&#x27;</span>，name=<span class="string">&#x27;22&#x27;</span>)</span><br><span class="line"><span class="comment">#输出结果2211</span></span><br></pre></td></tr></table></div></figure><p>使用关键字参数，可以有效避免因不小心搞乱参数的顺序导致的BUG出现</p>        <h3 id="3-python的return语句可以返回多个不同类型的值吗？"   >          <a href="#3-python的return语句可以返回多个不同类型的值吗？" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-python的return语句可以返回多个不同类型的值吗？" class="headerlink" title="3.python的return语句可以返回多个不同类型的值吗？"></a>3.python的return语句可以返回多个不同类型的值吗？</h3>      <p>可以，默认用逗号隔开，以元组的方式返回，也可以用列表的方式返回</p><blockquote><blockquote><blockquote><p>def myFun():<br>return ‘你’, 520, 3.14, True</p></blockquote></blockquote></blockquote><blockquote><blockquote><blockquote><p>myFun()<br>(‘你’, 520, 3.14, True)<br>def myFun2():<br>return [‘我’, 1314, 5.12, False]</p></blockquote></blockquote></blockquote><blockquote><blockquote><blockquote><p>myFun2()<br>[‘我’, 1314, 5.12, False]</p></blockquote></blockquote></blockquote>        <h3 id="4-全局变量global的使用"   >          <a href="#4-全局变量global的使用" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-全局变量global的使用" class="headerlink" title="4.全局变量global的使用"></a>4.全局变量global的使用</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">x = <span class="number">10</span>  <span class="comment"># 全局变量</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">func</span>():</span><br><span class="line">    x = <span class="number">20</span>  <span class="comment"># 这里实际上是创建了一个新的局部变量 x，而不是修改全局的 x</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;函数内部 x =&quot;</span>, x)</span><br><span class="line"></span><br><span class="line">func()</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;函数外部 x =&quot;</span>, x)</span><br></pre></td></tr></table></div></figure><p>输出结果：函数内部 x &#x3D; 20 函数外部 x &#x3D; 10</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">x = 10  # 全局变量</span><br><span class="line"></span><br><span class="line">def func():</span><br><span class="line">    global x  # 声明 x 是全局变量</span><br><span class="line">    x = 20    # 现在修改的是全局的 x</span><br><span class="line">    print(&quot;函数内部 x =&quot;, x)</span><br><span class="line"></span><br><span class="line">func()</span><br><span class="line">print(&quot;函数外部 x =&quot;, x)</span><br></pre></td></tr></table></div></figure><p>输出结果：函数内部 x &#x3D; 20 函数外部 x &#x3D; 20</p>        <h3 id="5-在嵌套函数中-如果希望在内部修改外部函数的局部变量，用什么关键字？"   >          <a href="#5-在嵌套函数中-如果希望在内部修改外部函数的局部变量，用什么关键字？" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-在嵌套函数中-如果希望在内部修改外部函数的局部变量，用什么关键字？" class="headerlink" title="5.在嵌套函数中,如果希望在内部修改外部函数的局部变量，用什么关键字？"></a>5.在嵌套函数中,如果希望在内部修改外部函数的局部变量，用什么关键字？</h3>      <p>nonlocal</p><blockquote><blockquote><blockquote><p>def Fun1():<br>   x &#x3D; 5<br>   def Fun2():<br>           nonlocal x<br>           x *&#x3D; x<br>           return x<br>   return Fun2()</p></blockquote></blockquote></blockquote><blockquote><blockquote><blockquote><p>Fun1()<br>25</p></blockquote></blockquote></blockquote>        <h3 id="6-如何利用函数闭包写一个计时器函数"   >          <a href="#6-如何利用函数闭包写一个计时器函数" class="heading-link"><i class="fas fa-link"></i></a><a href="#6-如何利用函数闭包写一个计时器函数" class="headerlink" title="6.如何利用函数闭包写一个计时器函数"></a>6.如何利用函数闭包写一个计时器函数</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">time_master</span>(<span class="params">func</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;开始运行程序&quot;</span>)</span><br><span class="line">    start=time.time()</span><br><span class="line">    func()</span><br><span class="line">    stop=time.time()</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&quot;程序运行时间为<span class="subst">&#123;(stop-start):<span class="number">.2</span>f&#125;</span>秒&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">myfunc</span>():</span><br><span class="line">    time.sleep(<span class="number">2</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;Hello World!&quot;</span>)</span><br><span class="line"></span><br><span class="line">time_master</span><br></pre></td></tr></table></div></figure><p>开始运行程序<br>Hello World!<br>程序运行时间为2.00秒</p>        <h3 id="7-如何不显式调用time-master-来实现一样的功能呢？"   >          <a href="#7-如何不显式调用time-master-来实现一样的功能呢？" class="heading-link"><i class="fas fa-link"></i></a><a href="#7-如何不显式调用time-master-来实现一样的功能呢？" class="headerlink" title="7.如何不显式调用time_master()来实现一样的功能呢？"></a>7.如何不显式调用time_master()来实现一样的功能呢？</h3>      <p>装饰器</p><figure class="highlight py"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">time_master</span>(<span class="params">func</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;开始运行程序&quot;</span>)</span><br><span class="line">    start=time.time()</span><br><span class="line">    func()</span><br><span class="line">    stop=time.time()</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&quot;程序运行时间为<span class="subst">&#123;(stop-start):<span class="number">.2</span>f&#125;</span>秒&quot;</span>)</span><br><span class="line">    </span><br><span class="line"><span class="meta">@time_master</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">myfunc</span>():</span><br><span class="line">    time.sleep(<span class="number">2</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;Hello World!&quot;</span>)</span><br></pre></td></tr></table></div></figure><p>这里装饰器的实质其实是</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">myfunc = time_master(myfunc)</span><br><span class="line">mufunc</span><br><span class="line"></span><br></pre></td></tr></table></div></figure>        <h3 id="8-装饰器可以嵌套使用吗？"   >          <a href="#8-装饰器可以嵌套使用吗？" class="heading-link"><i class="fas fa-link"></i></a><a href="#8-装饰器可以嵌套使用吗？" class="headerlink" title="8.装饰器可以嵌套使用吗？"></a>8.装饰器可以嵌套使用吗？</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">add</span>(<span class="params">func</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">inner</span>():</span><br><span class="line">        x = func()</span><br><span class="line">        <span class="keyword">return</span> x + <span class="number">1</span></span><br><span class="line">    <span class="keyword">return</span> inner</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">cube</span>(<span class="params">func</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">inner</span>():</span><br><span class="line">        x = func()</span><br><span class="line">        <span class="keyword">return</span> x*x*x</span><br><span class="line">    <span class="keyword">return</span> inner</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">square</span>(<span class="params">func</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">inner</span>():</span><br><span class="line">        x = func()</span><br><span class="line">        <span class="keyword">return</span> x*x</span><br><span class="line">    <span class="keyword">return</span> inner</span><br><span class="line"></span><br><span class="line"><span class="meta">@add</span></span><br><span class="line"><span class="meta">@cube</span></span><br><span class="line"><span class="meta">@square</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test</span>():</span><br><span class="line">    <span class="keyword">return</span> <span class="number">2</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(test())</span><br></pre></td></tr></table></div></figure><p>输出结果：65</p>        <h3 id="9-map函数和lambda表达式"   >          <a href="#9-map函数和lambda表达式" class="heading-link"><i class="fas fa-link"></i></a><a href="#9-map函数和lambda表达式" class="headerlink" title="9.map函数和lambda表达式"></a>9.map函数和lambda表达式</h3>      <p>可以将一个函数应用于一个或多个可迭代对象（如列表元组）的每个元素，并返回一个迭代器</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">map</span>(function,iterable.……)</span><br></pre></td></tr></table></div></figure><p>function：要应用的函数</p><p>iterable :一个或多个可迭代对象</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">*<span class="comment"># 将列表中的每个数字平方*</span></span><br><span class="line">numbers = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>] </span><br><span class="line">squared = <span class="built_in">map</span>(<span class="keyword">lambda</span> x: x**<span class="number">2</span>, numbers) </span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(squared))  *<span class="comment"># 输出: [1, 4, 9, 16, 25]*</span></span><br><span class="line"></span><br></pre></td></tr></table></div></figure><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 将两个列表的对应元素相加</span></span><br><span class="line">nums1 = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]</span><br><span class="line">nums2 = [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]</span><br><span class="line">result = <span class="built_in">map</span>(<span class="keyword">lambda</span> x, y: x + y, nums1, nums2)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(result))  <span class="comment"># 输出: [5, 7, 9]</span></span><br></pre></td></tr></table></div></figure><p>还可以与内置函数结合使用</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 计算列表中每个字符串的长度</span></span><br><span class="line">words = [<span class="string">&#x27;apple&#x27;</span>, <span class="string">&#x27;banana&#x27;</span>, <span class="string">&#x27;cherry&#x27;</span>]</span><br><span class="line">lengths = <span class="built_in">map</span>(<span class="built_in">len</span>, words)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>(lengths))  <span class="comment"># 输出: [5, 6, 6]</span></span><br></pre></td></tr></table></div></figure>        <h3 id="10-请使用lambda表达式将下边函数转变为匿名函数？"   >          <a href="#10-请使用lambda表达式将下边函数转变为匿名函数？" class="heading-link"><i class="fas fa-link"></i></a><a href="#10-请使用lambda表达式将下边函数转变为匿名函数？" class="headerlink" title="10. 请使用lambda表达式将下边函数转变为匿名函数？"></a>10. 请使用lambda表达式将下边函数转变为匿名函数？</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">fun_A</span>(<span class="params">x, y=<span class="number">3</span></span>):</span><br><span class="line">        <span class="keyword">return</span> x * y</span><br></pre></td></tr></table></div></figure><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">lambda</span> x,y=<span class="number">3</span> : x*y</span><br></pre></td></tr></table></div></figure>        <h3 id="11-你可以利用filter-和lambda表达式快速求出100以内所有3的倍数吗？"   >          <a href="#11-你可以利用filter-和lambda表达式快速求出100以内所有3的倍数吗？" class="heading-link"><i class="fas fa-link"></i></a><a href="#11-你可以利用filter-和lambda表达式快速求出100以内所有3的倍数吗？" class="headerlink" title="11. 你可以利用filter()和lambda表达式快速求出100以内所有3的倍数吗？"></a>11. 你可以利用filter()和lambda表达式快速求出100以内所有3的倍数吗？</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">list</span>(<span class="built_in">filter</span>(<span class="keyword">lambda</span> n : <span class="keyword">not</span>(n%<span class="number">3</span>), <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">100</span>)))</span><br></pre></td></tr></table></div></figure>        <h3 id="12-还记得列表推导式吗？完全可以使用列表推导式代替filter-和lambda组合，你可以做到吗？"   >          <a href="#12-还记得列表推导式吗？完全可以使用列表推导式代替filter-和lambda组合，你可以做到吗？" class="heading-link"><i class="fas fa-link"></i></a><a href="#12-还记得列表推导式吗？完全可以使用列表推导式代替filter-和lambda组合，你可以做到吗？" class="headerlink" title="12. 还记得列表推导式吗？完全可以使用列表推导式代替filter()和lambda组合，你可以做到吗？"></a>12. 还记得列表推导式吗？完全可以使用列表推导式代替filter()和<span class="exturl"><a class="exturl__link"   href="https://so.csdn.net/so/search?q=lambda&spm=1001.2101.3001.7020" >lambda</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span>组合，你可以做到吗？</h3>      <p>例如将第3题转为列表推导式即：</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[ i <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">100</span>) <span class="keyword">if</span> <span class="keyword">not</span>(i%<span class="number">3</span>)]</span><br></pre></td></tr></table></div></figure>        <h3 id="13-还记得zip吗？使用zip会将两数以元祖的形式绑定在一块，例如："   >          <a href="#13-还记得zip吗？使用zip会将两数以元祖的形式绑定在一块，例如：" class="heading-link"><i class="fas fa-link"></i></a><a href="#13-还记得zip吗？使用zip会将两数以元祖的形式绑定在一块，例如：" class="headerlink" title="13.还记得zip吗？使用zip会将两数以元祖的形式绑定在一块，例如："></a>13.还记得zip吗？使用zip会将两数以元祖的形式绑定在一块，例如：</h3>      <blockquote><blockquote><blockquote><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">list</span>(<span class="built_in">zip</span>([<span class="number">1</span>, <span class="number">3</span>, <span class="number">5</span>, <span class="number">7</span>, <span class="number">9</span>], [<span class="number">2</span>, <span class="number">4</span>, <span class="number">6</span>, <span class="number">8</span>, <span class="number">10</span>]))</span><br><span class="line">[(<span class="number">1</span>, <span class="number">2</span>), (<span class="number">3</span>, <span class="number">4</span>), (<span class="number">5</span>, <span class="number">6</span>), (<span class="number">7</span>, <span class="number">8</span>), (<span class="number">9</span>, <span class="number">10</span>)]</span><br></pre></td></tr></table></div></figure><p>但如果我希望打包的形式是灵活多变的列表而不是元祖（希望是[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]这种形式），你能做到吗？（采用map和lambda表达式）</p></blockquote></blockquote></blockquote><blockquote><blockquote><blockquote><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">list</span>(<span class="built_in">map</span>(<span class="keyword">lambda</span> x, y : [x, y], [<span class="number">1</span>, <span class="number">3</span>, <span class="number">5</span>, <span class="number">7</span>, <span class="number">9</span>], [<span class="number">2</span>, <span class="number">4</span>, <span class="number">6</span>, <span class="number">8</span>, <span class="number">10</span>]))</span><br><span class="line">[[<span class="number">1</span>, <span class="number">2</span>], [<span class="number">3</span>, <span class="number">4</span>], [<span class="number">5</span>, <span class="number">6</span>], [<span class="number">7</span>, <span class="number">8</span>], [<span class="number">9</span>, <span class="number">10</span>]]</span><br></pre></td></tr></table></div></figure><p>注意：强大的map()后边是可以接受多个序列作为参数的</p></blockquote></blockquote></blockquote>        <h3 id="14-生成器-yield"   >          <a href="#14-生成器-yield" class="heading-link"><i class="fas fa-link"></i></a><a href="#14-生成器-yield" class="headerlink" title="14.生成器 yield"></a>14.生成器 yield</h3>      <p>逐步产生值而不是一次性返回所有结果。当调用生成器函数时，它不会立即执行，而是返回一个生成器对象，这个对象可以迭代</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#创建生成器函数</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">gen</span>():</span><br><span class="line"><span class="keyword">yield</span> value</span><br><span class="line"></span><br><span class="line"><span class="comment">#简单示例</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">gen</span>():</span><br><span class="line"><span class="keyword">yield</span> <span class="number">1</span></span><br><span class="line"><span class="keyword">yield</span> <span class="number">2</span></span><br><span class="line"><span class="keyword">yield</span> <span class="number">3</span></span><br><span class="line"></span><br><span class="line">gen1=gen()</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(gen))<span class="comment">#输出1</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(gen))<span class="comment">#输出2</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(gen))<span class="comment">#输出3</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(gen))<span class="comment">#输出抛出 stopiteration异常</span></span><br></pre></td></tr></table></div></figure>        <h3 id="15-如何用生成器生成斐波那契数列"   >          <a href="#15-如何用生成器生成斐波那契数列" class="heading-link"><i class="fas fa-link"></i></a><a href="#15-如何用生成器生成斐波那契数列" class="headerlink" title="15.如何用生成器生成斐波那契数列"></a>15.如何用生成器生成斐波那契数列</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">fiber</span>():</span><br><span class="line">a,b=<span class="number">0</span>,<span class="number">1</span></span><br><span class="line"><span class="keyword">while</span> true:</span><br><span class="line"><span class="keyword">yield</span> a</span><br><span class="line">a,b=b,a+b</span><br><span class="line"></span><br><span class="line">f=fiber()</span><br><span class="line"><span class="built_in">next</span>(f)<span class="comment">#输出0</span></span><br><span class="line"><span class="built_in">next</span>(f)<span class="comment">#输出1</span></span><br><span class="line"><span class="built_in">next</span>(f)<span class="comment">#输出1</span></span><br><span class="line"><span class="built_in">next</span>(f)<span class="comment">#输出2</span></span><br></pre></td></tr></table></div></figure>        <h3 id="16-生成器表达式"   >          <a href="#16-生成器表达式" class="heading-link"><i class="fas fa-link"></i></a><a href="#16-生成器表达式" class="headerlink" title="16.生成器表达式"></a>16.生成器表达式</h3>      <p>类似于列表推导式，但使用圆括号并返回生成器：</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 列表推导式 - 立即计算</span></span><br><span class="line">squares_list = [x**<span class="number">2</span> <span class="keyword">for</span> x <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>)]  <span class="comment"># 返回列表</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 生成器表达式 - 惰性计算</span></span><br><span class="line">squares_gen = (x**<span class="number">2</span> <span class="keyword">for</span> x <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>))  <span class="comment"># 返回生成器</span></span><br></pre></td></tr></table></div></figure>        <h3 id="17-用迭代和递归的方式分别实现求一个数的阶乘"   >          <a href="#17-用迭代和递归的方式分别实现求一个数的阶乘" class="heading-link"><i class="fas fa-link"></i></a><a href="#17-用迭代和递归的方式分别实现求一个数的阶乘" class="headerlink" title="17.用迭代和递归的方式分别实现求一个数的阶乘"></a>17.用迭代和递归的方式分别实现求一个数的阶乘</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">gui</span>(<span class="params">i</span>):</span><br><span class="line"><span class="keyword">if</span> n==<span class="number">1</span> :</span><br><span class="line"><span class="keyword">return</span> <span class="number">1</span></span><br><span class="line"><span class="keyword">else</span></span><br><span class="line"><span class="keyword">return</span> n*gui(n-<span class="number">1</span>)</span><br><span class="line">    </span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fact</span>(<span class="params">i</span>):</span><br><span class="line">result = n</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>,n):</span><br><span class="line">result*=i</span><br><span class="line"><span class="keyword">return</span> result</span><br><span class="line"></span><br></pre></td></tr></table></div></figure>        <h3 id="18-用递归求斐波那契"   >          <a href="#18-用递归求斐波那契" class="heading-link"><i class="fas fa-link"></i></a><a href="#18-用递归求斐波那契" class="headerlink" title="18.用递归求斐波那契"></a>18.用递归求斐波那契</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">gui</span>(<span class="params">i</span>):</span><br><span class="line"><span class="keyword">if</span> i==<span class="number">1</span> <span class="keyword">or</span> i==<span class="number">2</span>:</span><br><span class="line"><span class="keyword">return</span> <span class="number">1</span></span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">    <span class="keyword">return</span> gui(n-<span class="number">1</span>)+gui(n-<span class="number">1</span>)</span><br></pre></td></tr></table></div></figure>        <h3 id="19-用递归实现汉诺塔"   >          <a href="#19-用递归实现汉诺塔" class="heading-link"><i class="fas fa-link"></i></a><a href="#19-用递归实现汉诺塔" class="headerlink" title="19.用递归实现汉诺塔"></a>19.用递归实现汉诺塔</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">hanoi</span>(<span class="params">n,x,y,z</span>):</span><br><span class="line"><span class="keyword">if</span> n == <span class="number">1</span></span><br><span class="line"><span class="built_in">print</span>(x,<span class="string">&quot;-&gt;&quot;</span>,z)<span class="comment">#如果只有一层，直接将金片从x移动到z</span></span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">hanoi(n-<span class="number">1</span>,x,z,y)<span class="comment">#将x上的n-1的金片移动到y</span></span><br><span class="line"><span class="built_in">print</span>(x,<span class="string">&#x27;-&gt;&#x27;</span>,z)<span class="comment">#最底下的金片从x到z</span></span><br><span class="line">hanoi(n-<span class="number">1</span>,y,x,z)<span class="comment">#将y上的n-1个金片移动到z</span></span><br><span class="line"></span><br><span class="line">n=<span class="built_in">int</span>(<span class="built_in">input</span>(请输入汉诺塔层数：))</span><br><span class="line">hanoi(n,<span class="string">&#x27;A&#x27;</span>,<span class="string">&#x27;b&#x27;</span>,<span class="string">&#x27;c&#x27;</span>)</span><br></pre></td></tr></table></div></figure>        <h3 id="20-函数文档以及内省展示"   >          <a href="#20-函数文档以及内省展示" class="heading-link"><i class="fas fa-link"></i></a><a href="#20-函数文档以及内省展示" class="headerlink" title="20.函数文档以及内省展示"></a>20.函数文档以及内省展示</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">exchange</span>(<span class="params">dollars,rate=<span class="number">6.5</span></span>):</span><br><span class="line">   <span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">   功能：汇率转换，美元-&gt;人民币</span></span><br><span class="line"><span class="string">   参数：</span></span><br><span class="line"><span class="string">   - dollars: 美元数</span></span><br><span class="line"><span class="string">   - rate: 汇率，默认6.5</span></span><br><span class="line"><span class="string">   返回值：人民币数</span></span><br><span class="line"><span class="string">   &quot;&quot;&quot;</span></span><br><span class="line">   <span class="keyword">return</span> dollars * rate</span><br><span class="line"><span class="built_in">print</span>(exchange.__doc__ )<span class="comment"># 查看函数的文档</span></span><br></pre></td></tr></table></div></figure><p>打印“功能：汇率转换，美元-&gt;人民币<br>参数：</p><ul><li>dollars: 美元数</li><li>rate: 汇率，默认6.5<br>返回值：人民币数”</li></ul>        <h3 id="21-类型注释"   >          <a href="#21-类型注释" class="heading-link"><i class="fas fa-link"></i></a><a href="#21-类型注释" class="headerlink" title="21.类型注释"></a>21.类型注释</h3>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">def times(s:str,n:int)-&gt;str:</span><br><span class="line">return s*n</span><br></pre></td></tr></table></div></figure><p>表示希望传入的s,n分别是字符串类型和Int型，并告诉你返回的是str</p><p>但这不是给编译器读的，是方便开发者记住的，不用严格按照期望传参</p>        <h3 id="22-什么是高阶函数"   >          <a href="#22-什么是高阶函数" class="heading-link"><i class="fas fa-link"></i></a><a href="#22-什么是高阶函数" class="headerlink" title="22.什么是高阶函数"></a>22.什么是高阶函数</h3>      <ol><li><strong>接受一个或多个函数作为参数</strong></li><li><strong>将一个函数作为返回值返回</strong></li></ol><p>简单来说，高阶函数就是“操作其他函数”的函数。这使得代码更加抽象、灵活和可复用。</p>        <h3 id="23-高阶函数有哪些，它们有什么作用？"   >          <a href="#23-高阶函数有哪些，它们有什么作用？" class="heading-link"><i class="fas fa-link"></i></a><a href="#23-高阶函数有哪些，它们有什么作用？" class="headerlink" title="23.高阶函数有哪些，它们有什么作用？"></a>23.高阶函数有哪些，它们有什么作用？</h3>      <p>Python 在 <code>functools</code>和内置命名空间中提供了几个非常实用的高阶函数，其中最著名的是 <code>map()</code>, <code>filter()</code>, 和 <code>reduce()</code>。</p><p><strong>1. map(function, iterable, …)</strong></p><p><code>map()</code>函数会将一个函数<strong>映射</strong>应用到可迭代对象（如列表、元组）的每一个元素上，并返回一个迭代器（在 Python 2 中返回列表，Python 3 中返回更高效的 <code>map</code>对象，通常需要转换成列表）。</p><ul><li><p><strong>作用</strong>：对可迭代对象中的每个元素进行某种转换。</p></li><li><p><strong>语法</strong>：<code>map(function, iterable)</code></p></li><li><pre><code class="language-python"> 定义一个平方函数def square(x):    return x ** 2numbers = [1, 2, 3, 4, 5]# 使用 mapsquared_numbers = map(square, numbers)print(list(squared_numbers))  # 输出: [1, 4, 9, 16, 25]# 更常见的做法是使用 lambda 匿名函数，使代码更简洁list1 = map(lambda x: x**2, numbers)print(list(list1))  # 输出: [1, 4, 9, 16, 25]<figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">**2. filter(function, iterable)**</span><br><span class="line"></span><br><span class="line">`filter()`函数用于**过滤**序列，根据一个返回布尔值（`True`或 `False`）的函数来筛选可迭代对象中满足条件（使函数返回 `True`）的元素，同样返回一个迭代器。</span><br><span class="line"></span><br><span class="line">- **作用**：从可迭代对象中筛选出符合条件的元素。</span><br><span class="line"></span><br><span class="line">- **语法**：`filter(function, iterable)`</span><br><span class="line"></span><br><span class="line">  ```py</span><br><span class="line">  numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]</span><br><span class="line">  </span><br><span class="line">  # 定义一个判断偶数的函数</span><br><span class="line">  def is_even(x):</span><br><span class="line">      return x % 2 == 0</span><br><span class="line">  </span><br><span class="line">  # 使用 filter</span><br><span class="line">  even_numbers = filter(is_even, numbers)</span><br><span class="line">  print(list(even_numbers))  # 输出: [2, 4, 6, 8, 10]</span><br><span class="line">  </span><br><span class="line">  # 使用 lambda 函数</span><br><span class="line">  even_numbers_lambda = filter(lambda x: x % 2 == 0, numbers)</span><br><span class="line">  print(list(even_numbers_lambda))  # 输出: [2, 4, 6, 8, 10]</span><br></pre></td></tr></table></div></figure>  **3. functools.reduce(function, iterable[, initializer])**  `reduce()`函数在 `functools`模块中，需要先导入。它会对序列中的元素进行**累积**操作。它接收一个二元函数（有两个参数的函数）、一个可迭代对象和一个可选的初始值。它会用这个二元函数从左到右依次对序列中的元素进行累积计算，最终将序列“缩减”为一个单一的返回值。  - **作用**：对序列中的元素进行累积运算。  - **语法**：`reduce(function, iterable[, initializer])`  - **计算过程**： `reduce(f, [a, b, c, d])`等价于 `f(f(f(a, b), c), d)`。    <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#计算阶乘</span></span><br><span class="line"><span class="keyword">import</span> functools</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">jiec</span>(<span class="params">x,y</span>):</span><br><span class="line"><span class="keyword">return</span> x*y</span><br><span class="line"></span><br><span class="line">num=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>]</span><br><span class="line">res=reduce(jiec,num)</span><br><span class="line"><span class="built_in">print</span>(res)<span class="comment">#输出24</span></span><br></pre></td></tr></table></div></figure></code></pre></li></ul>        <h3 id="24-wraps装饰器的作用"   >          <a href="#24-wraps装饰器的作用" class="heading-link"><i class="fas fa-link"></i></a><a href="#24-wraps装饰器的作用" class="headerlink" title="24.wraps装饰器的作用"></a>24.wraps装饰器的作用</h3>      <p>在讲解装饰器时，用到了以下代码</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">time_master</span>(<span class="params">func</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">call_func</span>():</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;开始运行程序&quot;</span>)</span><br><span class="line">        start=time.time</span><br><span class="line">        func()</span><br><span class="line">        end=time.time</span><br><span class="line">        ptint(<span class="string">f&quot;程序一共运行<span class="subst">&#123;(end=start):<span class="number">.2</span>f&#125;</span>秒。&quot;</span>)</span><br><span class="line">     <span class="keyword">return</span> call_func</span><br><span class="line"></span><br><span class="line"><span class="meta">@time_master</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">myfunc</span>():</span><br><span class="line">    time.sleep(<span class="number">2</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="number">11111</span>)</span><br><span class="line">    </span><br><span class="line"><span class="comment">#此时如果你输出myfunc.__name__，会发现输出的是call_func，因为实际调用的其实是这个函数，人们为了避免这一情况，发明了@wraps</span></span><br></pre></td></tr></table></div></figure><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">import</span> functools</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">time_master</span>(<span class="params">func</span>):</span><br><span class="line"><span class="meta">    @dunctools.wraps(<span class="params">func</span>)</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">call_func</span>():</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;开始运行程序&quot;</span>)</span><br><span class="line">        start=time.time</span><br><span class="line">        func()</span><br><span class="line">        end=time.time</span><br><span class="line">        ptint(<span class="string">f&quot;程序一共运行<span class="subst">&#123;(end=start):<span class="number">.2</span>f&#125;</span>秒。&quot;</span>)</span><br><span class="line">     <span class="keyword">return</span> call_func</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">myfunc</span>():</span><br><span class="line">    time.sleep(<span class="number">2</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="number">11111</span>)</span><br></pre></td></tr></table></div></figure><p>此时再打印，就是func了</p>        <h3 id="25-文件操作有哪些方法"   >          <a href="#25-文件操作有哪些方法" class="heading-link"><i class="fas fa-link"></i></a><a href="#25-文件操作有哪些方法" class="headerlink" title="25.文件操作有哪些方法"></a>25.文件操作有哪些方法</h3>      <p>1.open方法</p><p>Python <strong>open()</strong> 方法用于打开一个文件，并返回文件对象。</p><p>在对文件进行处理过程都需要使用到这个函数，如果该文件无法被打开，会抛出 <strong>OSError</strong>。</p><p>**注意：**使用 <strong>open()</strong> 方法一定要保证关闭文件对象，即调用 <strong>close()</strong> 方法。</p><p><strong>open()</strong> 函数常用形式是接收两个参数：文件名(file)和模式(mode)。</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">open</span>(file, mode=<span class="string">&#x27;r&#x27;</span>)</span><br><span class="line">mode参数有哪些</span><br></pre></td></tr></table></div></figure><div class="table-container"><table><thead><tr><th align="left">模式</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">t</td><td align="left">文本模式 (默认)。</td></tr><tr><td align="left">x</td><td align="left">写模式，新建一个文件，如果该文件已存在则会报错。</td></tr><tr><td align="left">b</td><td align="left">二进制模式。</td></tr><tr><td align="left">+</td><td align="left">打开一个文件进行更新(可读可写)。</td></tr><tr><td align="left">U</td><td align="left">通用换行模式（<strong>Python 3 不支持</strong>）。</td></tr><tr><td align="left">r</td><td align="left">以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。</td></tr><tr><td align="left">rb</td><td align="left">以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。</td></tr><tr><td align="left">r+</td><td align="left">打开一个文件用于读写。文件指针将会放在文件的开头。</td></tr><tr><td align="left">rb+</td><td align="left">以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。</td></tr><tr><td align="left">w</td><td align="left">打开一个文件只用于写入。如果该文件已存在则打开文件，并从开头开始编辑，即原有内容会被删除。如果该文件不存在，创建新文件。</td></tr><tr><td align="left">wb</td><td align="left">以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件，并从开头开始编辑，即原有内容会被删除。如果该文件不存在，创建新文件。一般用于非文本文件如图片等。</td></tr><tr><td align="left">w+</td><td align="left">打开一个文件用于读写。如果该文件已存在则打开文件，并从开头开始编辑，即原有内容会被删除。如果该文件不存在，创建新文件。</td></tr><tr><td align="left">wb+</td><td align="left">以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件，并从开头开始编辑，即原有内容会被删除。如果该文件不存在，创建新文件。一般用于非文本文件如图片等。</td></tr><tr><td align="left">a</td><td align="left">打开一个文件用于追加。如果该文件已存在，文件指针将会放在文件的结尾。也就是说，新的内容将会被写入到已有内容之后。如果该文件不存在，创建新文件进行写入。</td></tr><tr><td align="left">ab</td><td align="left">以二进制格式打开一个文件用于追加。如果该文件已存在，文件指针将会放在文件的结尾。也就是说，新的内容将会被写入到已有内容之后。如果该文件不存在，创建新文件进行写入。</td></tr><tr><td align="left">a+</td><td align="left">打开一个文件用于读写。如果该文件已存在，文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在，创建新文件用于读写。</td></tr><tr><td align="left">ab+</td><td align="left">以二进制格式打开一个文件用于追加。如果该文件已存在，文件指针将会放在文件的结尾。如果该文件不存在，创建新文件用于读写。</td></tr></tbody></table></div><p>默认为文本模式，如果要以二进制模式打开，加上 <strong>b</strong> 。</p><p>open是传统方法，我们更推荐使用with</p>        <h3 id="26-什么是with语句"   >          <a href="#26-什么是with语句" class="heading-link"><i class="fas fa-link"></i></a><a href="#26-什么是with语句" class="headerlink" title="26.什么是with语句"></a>26.什么是with语句</h3>      <p><code>with</code>语句是 Python 中用于资源管理的上下文管理协议实现，特别适合文件操作等需要明确释放资源的场景。</p><p>文件操作场景</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 传统方式（不推荐）</span></span><br><span class="line">f = <span class="built_in">open</span>(<span class="string">&#x27;file.txt&#x27;</span>, <span class="string">&#x27;r&#x27;</span>)</span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    data = f.read()</span><br><span class="line">    <span class="comment"># 处理文件内容</span></span><br><span class="line"><span class="keyword">finally</span>:</span><br><span class="line">    f.close()  <span class="comment"># 必须确保关闭文件</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># with 语句方式（推荐）</span></span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&#x27;file.txt&#x27;</span>, <span class="string">&#x27;r&#x27;</span>) <span class="keyword">as</span> f:</span><br><span class="line">    data = f.read()</span><br><span class="line">    <span class="comment"># 处理文件内容</span></span><br><span class="line"><span class="comment"># 文件会在代码块结束后自动关闭</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用 with 写入文件</span></span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&#x27;output.txt&#x27;</span>, <span class="string">&#x27;w&#x27;</span>) <span class="keyword">as</span> file:</span><br><span class="line">    file.write(<span class="string">&#x27;第一行内容\n&#x27;</span>)</span><br><span class="line">    file.write(<span class="string">&#x27;第二行内容\n&#x27;</span>)</span><br><span class="line"><span class="comment"># 文件已自动关闭且内容已保存</span></span><br></pre></td></tr></table></div></figure><p>数据库连接场景</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> sqlite3</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用 with 管理数据库连接</span></span><br><span class="line"><span class="keyword">with</span> sqlite3.connect(<span class="string">&#x27;example.db&#x27;</span>) <span class="keyword">as</span> conn:</span><br><span class="line">    cursor = conn.cursor()</span><br><span class="line">    cursor.execute(<span class="string">&#x27;SELECT * FROM users&#x27;</span>)</span><br><span class="line">    results = cursor.fetchall()</span><br><span class="line"><span class="comment"># 连接自动关闭</span></span><br></pre></td></tr></table></div></figure><p><img src="/images/image-20250913103903612.png" alt="image-20250913103903612"></p>        <h3 id="27-Pashlib中path的使用（旧版本使用os-path）"   >          <a href="#27-Pashlib中path的使用（旧版本使用os-path）" class="heading-link"><i class="fas fa-link"></i></a><a href="#27-Pashlib中path的使用（旧版本使用os-path）" class="headerlink" title="27.Pashlib中path的使用（旧版本使用os.path）"></a>27.Pashlib中path的使用（旧版本使用os.path）</h3>      <p><strong>1.创建</strong></p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> pathlib <span class="keyword">import</span> Path</span><br><span class="line"></span><br><span class="line"><span class="comment">#创建Path对象</span></span><br><span class="line">p=Path(<span class="string">&#x27;D:/python/1.py&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(p)</span><br><span class="line"></span><br><span class="line">p1=Path(<span class="string">&#x27;D:/python&#x27;</span>)</span><br><span class="line">p2=p1/<span class="string">&#x27;123&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(p2)</span><br></pre></td></tr></table></div></figure><p>输出结果 D:\python\1.py</p><p>D:\python\123</p><p><u><strong>注意斜杠和反斜杠</strong></u></p><p><strong>2.cwd()获取当前路径</strong></p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">path=Path.cwd()</span><br><span class="line"><span class="built_in">print</span>(path)</span><br></pre></td></tr></table></div></figure><p>D：\python</p><p><strong>3.Path.stat获取当前文件信息</strong></p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">p=Path(&#x27;1.py&#x27;)</span><br><span class="line">print(p.stat())</span><br></pre></td></tr></table></div></figure><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">jos.stat_result(st_mode=33206, st_ino=8444249301448143, st_dev=2561774433, st_nlink=1, st_uid=0, st_gid=0, st_size=4, st_atime=1525926554, st_mtime=1525926554, st_ctime=1525926554)</span><br></pre></td></tr></table></div></figure><p><strong>4.Path.exists判断当前路径是否是文件或文件夹</strong></p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>Path(<span class="string">&#x27;.&#x27;</span>).exists()</span><br><span class="line"><span class="literal">True</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>Path(<span class="string">&#x27;1.py&#x27;</span>).exists()</span><br><span class="line"><span class="literal">True</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>Path(<span class="string">&#x27;2.py&#x27;</span>).exists()</span><br><span class="line"><span class="literal">False</span></span><br></pre></td></tr></table></div></figure><p><strong>5.Path.is_dir()判断该路径是否是文件夹，Path.is_file()判断该路径是否是文件</strong></p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;p1:&#x27;</span>)</span><br><span class="line">p1 = Path(<span class="string">&#x27;D:/python&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(p1.is_dir())</span><br><span class="line"><span class="built_in">print</span>(p1.is_file())</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;p2:&#x27;</span>)</span><br><span class="line">p2 = Path(<span class="string">&#x27;D:/python/1.py&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(p2.is_dir())</span><br><span class="line"><span class="built_in">print</span>(p2.is_file())</span><br><span class="line"></span><br><span class="line"><span class="comment">#当路径不存在时也会返回Fasle</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;wrong path:&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(Path(<span class="string">&#x27;D:/NoneExistsPath&#x27;</span>).is_dir())</span><br><span class="line"><span class="built_in">print</span>(Path(<span class="string">&#x27;D:/NoneExistsPath&#x27;</span>).is_file())</span><br></pre></td></tr></table></div></figure><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">p1:</span><br><span class="line">True</span><br><span class="line">False</span><br><span class="line">p2:</span><br><span class="line">False</span><br><span class="line">True</span><br><span class="line">wrong path:</span><br><span class="line">False</span><br><span class="line">False</span><br></pre></td></tr></table></div></figure><p><strong>6.Path.iterdir()</strong></p><p>当path为文件夹时，通过yield产生path文件夹下的所有文件、文件夹路径的迭代器</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">p = Path.cwd()</span><br><span class="line">for i in p.iterdir():</span><br><span class="line">    print(i)</span><br></pre></td></tr></table></div></figure><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">D:\python\1.py</span><br><span class="line">D:\python\11.py</span><br><span class="line">D:\python\1111.py</span><br><span class="line">D:\python\11111.py</span><br><span class="line">D:\python\dir</span><br></pre></td></tr></table></div></figure><p><strong>7.Path.rename(target)</strong></p><p>当targrt是string时，重命名文件或文件夹</p><p>当target是path时，重命名并移动文件或文件夹</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">p1 = Path(&#x27;1.py&#x27;)</span><br><span class="line">p1.rename(&#x27;new_name.py&#x27;)</span><br><span class="line"></span><br><span class="line">p2 = Path(&#x27;11.py&#x27;)</span><br><span class="line">target = Path(&#x27;new_dir/new_name.py&#x27;)</span><br><span class="line">p2.rename(target)</span><br></pre></td></tr></table></div></figure><p>12.Path.replace(target)<br>重命名当前文件或文件夹，如果target所指示的文件或文件夹已存在，则覆盖原文件</p><p>13.Path.parent(),Path.parents()</p>        <h3 id="parent获取path的上级路径，parents获取path的所有上级路径"   >          <a href="#parent获取path的上级路径，parents获取path的所有上级路径" class="heading-link"><i class="fas fa-link"></i></a><a href="#parent获取path的上级路径，parents获取path的所有上级路径" class="headerlink" title="parent获取path的上级路径，parents获取path的所有上级路径"></a>parent获取path的上级路径，parents获取path的所有上级路径</h3>      <p>14.Path.is_absolute()<br>判断path是否是绝对路径</p><p>15.Path.match(pattern)<br>判断path是否满足pattern</p><p>16.Path.rmdir()<br>当path为空文件夹的时候，删除该文件夹</p><p>17.Path.name<br>获取path文件名</p><p>18.Path.suffix<br>获取path文件后缀</p>        <h3 id="28-Pickle模块"   >          <a href="#28-Pickle模块" class="heading-link"><i class="fas fa-link"></i></a><a href="#28-Pickle模块" class="headerlink" title="28.Pickle模块"></a>28.Pickle模块</h3>      <p>将Python对象序列化（二进制）</p><p>使用dump和</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> pickle</span><br><span class="line">x,y,z=<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span></span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&quot;date.pkl&quot;</span>,<span class="string">&quot;wb&quot;</span>) <span class="keyword">as</span> f:</span><br><span class="line">pickle.dump(x,f)</span><br><span class="line"></span><br><span class="line"><span class="comment">#文件中是一堆乱码</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&quot;date.pkl&quot;</span>,<span class="string">&quot;rb&quot;</span>) <span class="keyword">as</span> f:</span><br><span class="line">pickle.load(f)</span><br><span class="line"></span><br><span class="line"><span class="comment">#可以读回来源码了</span></span><br></pre></td></tr></table></div></figure>        <h3 id="29-异常（Exception）"   >          <a href="#29-异常（Exception）" class="heading-link"><i class="fas fa-link"></i></a><a href="#29-异常（Exception）" class="headerlink" title="29.异常（Exception）"></a>29.异常（Exception）</h3>      <p>在python中如果你违背了python的语法规则或者其他原因，就会出现异常，此时编译器会给你红色报错</p><p>例如</p><p>如果你计算 1&#x2F;0 ，我们知道0不能被除，那么就会抛出<code>ZeroDivisionerror</code>异常</p><p>如果你用字符串和数字相加，就会抛出<code>TypeError</code>异常</p><p>那么有没有什么办法让我们可以提前避免报错发现异常并修正呢</p><p><strong>try except语句</strong></p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    <span class="number">520</span>+<span class="string">&quot;fish&quot;</span></span><br><span class="line"><span class="keyword">except</span> TypeError:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;出错了&quot;</span>)</span><br><span class="line">    </span><br></pre></td></tr></table></div></figure><p>当然，如果错误类型不匹配的话，是无法匹配的，也就是说如果你把上面的换成<code>ZeroDivisionError</code></p><p>仍然会报错。</p><p>你也可以同时捕获多种异常，比如<code>except（ZeroDivisionerror，TypeError）</code></p><p>你也可以不选择具体类型的异常</p><p><strong>try except else finally</strong> </p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    <span class="comment"># 可能引发异常的代码</span></span><br><span class="line">    risky_operation()</span><br><span class="line"><span class="keyword">except</span> SpecificError <span class="keyword">as</span> e:</span><br><span class="line">    <span class="comment"># 处理特定异常</span></span><br><span class="line">    handle_error(e)</span><br><span class="line"><span class="keyword">except</span> AnotherError <span class="keyword">as</span> e:</span><br><span class="line">    <span class="comment"># 处理另一种异常</span></span><br><span class="line">    handle_another(e)</span><br><span class="line"><span class="keyword">except</span> Exception <span class="keyword">as</span> e:</span><br><span class="line">    <span class="comment"># 捕获所有其他异常</span></span><br><span class="line">    handle_generic(e)</span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">    <span class="comment"># 没有异常时执行</span></span><br><span class="line">    on_success()</span><br><span class="line"><span class="keyword">finally</span>:</span><br><span class="line">    <span class="comment"># 无论是否异常都执行</span></span><br><span class="line">    cleanup()</span><br></pre></td></tr></table></div></figure><p><strong>raise</strong></p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 主动抛出异常</span></span><br><span class="line"><span class="keyword">if</span> bad_condition:</span><br><span class="line">    <span class="keyword">raise</span> ValueError(<span class="string">&quot;说明错误原因&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 重新抛出当前异常</span></span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    something()</span><br><span class="line"><span class="keyword">except</span> SomeError:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;处理部分异常&quot;</span>)</span><br><span class="line">    <span class="keyword">raise</span>  <span class="comment"># 重新抛出给上层处理</span></span><br></pre></td></tr></table></div></figure><p><strong>assert</strong></p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 断言条件为真，否则抛出 AssertionError</span></span><br><span class="line"><span class="keyword">assert</span> condition, <span class="string">&quot;错误信息&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 等价于</span></span><br><span class="line"><span class="keyword">if</span> <span class="keyword">not</span> condition:</span><br><span class="line">    <span class="keyword">raise</span> AssertionError(<span class="string">&quot;错误信息&quot;</span>)</span><br></pre></td></tr></table></div></figure>]]></content>
      
      
      <categories>
          
          <category> python学习 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> python </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>列表元组字符串</title>
      <link href="/2025/09/09/%E5%88%97%E8%A1%A8%E5%85%83%E7%BB%84%E5%AD%97%E7%AC%A6%E4%B8%B2/"/>
      <url>/2025/09/09/%E5%88%97%E8%A1%A8%E5%85%83%E7%BB%84%E5%AD%97%E7%AC%A6%E4%B8%B2/</url>
      
        <content type="html"><![CDATA[        <h3 id="1-列表都可以存放一些什么东西？"   >          <a href="#1-列表都可以存放一些什么东西？" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-列表都可以存放一些什么东西？" class="headerlink" title="1. 列表都可以存放一些什么东西？"></a><strong>1.</strong> <strong>列表都可以存放一些什么东西？</strong></h3>      <p>我们说 Python 的列表是一个打了激素的数组，如果把数组比喻成集装箱，那么 Python 的列表就是一个大仓库，Ta 可以存放我们已经学习过的任何数据类型。</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mix = [1, ‘小’, 3.14, [1, 2, 3]]</span><br></pre></td></tr></table></div></figure>        <h3 id="2-向列表增加元素有哪些方法？"   >          <a href="#2-向列表增加元素有哪些方法？" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-向列表增加元素有哪些方法？" class="headerlink" title="2. 向列表增加元素有哪些方法？"></a><strong>2. 向列表增加元素有哪些方法？</strong></h3>      <p>append(),extend(),insert()</p>        <h5 id="extend-和append-都是向列表末端添加元素，区别在于："   >          <a href="#extend-和append-都是向列表末端添加元素，区别在于：" class="heading-link"><i class="fas fa-link"></i></a><a href="#extend-和append-都是向列表末端添加元素，区别在于：" class="headerlink" title="extend()和append()都是向列表末端添加元素，区别在于："></a>extend()和append()都是向列表末端添加元素，区别在于：</h5>      <p>append是将参数作为一个元素添加到列表的末尾</p><p>extend是将参数作为一个列表去扩展列表的末尾</p><blockquote><blockquote><blockquote><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">name = [<span class="string">&#x27;F&#x27;</span>, <span class="string">&#x27;i&#x27;</span>, <span class="string">&#x27;s&#x27;</span>, <span class="string">&#x27;h&#x27;</span>]</span><br><span class="line">name.append(<span class="string">&#x27;C&#x27;</span>)</span><br><span class="line">name</span><br><span class="line">[<span class="string">&#x27;F&#x27;</span>, <span class="string">&#x27;i&#x27;</span>, <span class="string">&#x27;s&#x27;</span>, <span class="string">&#x27;h&#x27;</span>, <span class="string">&#x27;C&#x27;</span>]</span><br><span class="line">name.extend([<span class="string">&#x27;.&#x27;</span>, <span class="string">&#x27;c&#x27;</span>])</span><br><span class="line">name</span><br><span class="line">[<span class="string">&#x27;F&#x27;</span>, <span class="string">&#x27;i&#x27;</span>, <span class="string">&#x27;s&#x27;</span>, <span class="string">&#x27;h&#x27;</span>, <span class="string">&#x27;C&#x27;</span>, <span class="string">&#x27;.&#x27;</span>, <span class="string">&#x27;c&#x27;</span>]</span><br><span class="line">name.append([<span class="string">&#x27;o&#x27;</span>, <span class="string">&#x27;m&#x27;</span>])</span><br><span class="line">name</span><br><span class="line">[<span class="string">&#x27;F&#x27;</span>, <span class="string">&#x27;i&#x27;</span>, <span class="string">&#x27;s&#x27;</span>, <span class="string">&#x27;h&#x27;</span>, <span class="string">&#x27;C&#x27;</span>, <span class="string">&#x27;.&#x27;</span>, <span class="string">&#x27;c&#x27;</span>, [<span class="string">&#x27;o&#x27;</span>, <span class="string">&#x27;m&#x27;</span>]]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">insert()：有两个参数，第一个参数是插入的位置，第二个参数是插入的元素</span><br><span class="line"></span><br><span class="line">member = [<span class="string">&#x27;小甲鱼&#x27;</span>, <span class="string">&#x27;小布丁&#x27;</span>, <span class="string">&#x27;小宝贝&#x27;</span>]</span><br><span class="line"></span><br><span class="line">\&gt;&gt;&gt; member.insert(<span class="number">1</span>, <span class="string">&#x27;厉害&#x27;</span>)</span><br><span class="line"></span><br><span class="line">\&gt;&gt;&gt; menber</span><br><span class="line"></span><br><span class="line">[<span class="string">&#x27;小甲鱼&#x27;</span>, <span class="string">&#x27;厉害&#x27;</span>, <span class="string">&#x27;小布丁&#x27;</span>, <span class="string">&#x27;小宝贝&#x27;</span>]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">### 3.for循环的应用</span></span><br><span class="line"></span><br><span class="line">```python</span><br><span class="line"></span><br><span class="line">member = [<span class="string">&#x27;小甲鱼&#x27;</span>, <span class="number">88</span>, <span class="string">&#x27;黑夜&#x27;</span>, <span class="number">90</span>, <span class="string">&#x27;迷途&#x27;</span>, <span class="number">85</span>, <span class="string">&#x27;怡静&#x27;</span>, <span class="number">90</span>, <span class="string">&#x27;秋舞斜阳&#x27;</span>, <span class="number">88</span>]</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> each <span class="keyword">in</span> member:</span><br><span class="line"></span><br><span class="line">​    <span class="built_in">print</span>(each)</span><br></pre></td></tr></table></div></figure></blockquote></blockquote></blockquote>        <h3 id="4-下边的列表分片操作会打印什么内容？"   >          <a href="#4-下边的列表分片操作会打印什么内容？" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-下边的列表分片操作会打印什么内容？" class="headerlink" title="4. 下边的列表分片操作会打印什么内容？"></a>4. 下边的列表分片操作会打印什么内容？</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">list1 = [<span class="number">1</span>, <span class="number">3</span>, <span class="number">2</span>, <span class="number">9</span>, <span class="number">7</span>, <span class="number">8</span>]</span><br><span class="line"></span><br><span class="line">list1[<span class="number">2</span>:<span class="number">5</span>]</span><br></pre></td></tr></table></div></figure><p>左闭右开 应该是[2,9,7]</p>        <h3 id="5-请问-list1-0-和-list1-0-1-一样吗？"   >          <a href="#5-请问-list1-0-和-list1-0-1-一样吗？" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-请问-list1-0-和-list1-0-1-一样吗？" class="headerlink" title="5. 请问 list1[0] 和 list1[0:1] 一样吗？"></a>5. 请问 list1[0] 和 list1[0:1] 一样吗？</h3>      <p>不一样，list1[0] 返回第0个元素的值，list1[0:1] 返回一个只含有第0个元素的列表。</p>        <h3 id="6-如果你每次想从列表的末尾取出一个元素，并将这个元素插入到列表的最前边，你会怎么做？"   >          <a href="#6-如果你每次想从列表的末尾取出一个元素，并将这个元素插入到列表的最前边，你会怎么做？" class="heading-link"><i class="fas fa-link"></i></a><a href="#6-如果你每次想从列表的末尾取出一个元素，并将这个元素插入到列表的最前边，你会怎么做？" class="headerlink" title="6.如果你每次想从列表的末尾取出一个元素，并将这个元素插入到列表的最前边，你会怎么做？"></a>6.如果你每次想从列表的末尾取出一个元素，并将这个元素插入到列表的最前边，你会怎么做？</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">list1.insert(<span class="number">0</span>,list1.pop())</span><br></pre></td></tr></table></div></figure>        <h3 id="7-在进行分片的时候，我们知道分片的开始和结束位置需要进行指定，但其实还有另外一个隐藏的设置：步长。"   >          <a href="#7-在进行分片的时候，我们知道分片的开始和结束位置需要进行指定，但其实还有另外一个隐藏的设置：步长。" class="heading-link"><i class="fas fa-link"></i></a><a href="#7-在进行分片的时候，我们知道分片的开始和结束位置需要进行指定，但其实还有另外一个隐藏的设置：步长。" class="headerlink" title="7. 在进行分片的时候，我们知道分片的开始和结束位置需要进行指定，但其实还有另外一个隐藏的设置：步长。"></a>7. 在进行分片的时候，我们知道分片的开始和结束位置需要进行指定，但其实还有另外一个隐藏的设置：步长。</h3>      <blockquote><p>在普通的分片操作中，步长默认设置为1，表示逐个遍历元素。其实我们可以人为调整步长以达到不可告人的秘密。</p></blockquote><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">list1 = [<span class="number">1</span>, <span class="number">3</span>, <span class="number">2</span>, <span class="number">9</span>, <span class="number">7</span>, <span class="number">8</span>]</span><br><span class="line">list1[<span class="number">0</span>:<span class="number">6</span>:<span class="number">2</span>]</span><br><span class="line">[<span class="number">1</span>, <span class="number">2</span>, <span class="number">7</span>]</span><br></pre></td></tr></table></div></figure><p>之前提到的“简洁”分片操作在这里有效：</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">list1[::<span class="number">2</span>]</span><br><span class="line"></span><br><span class="line">[<span class="number">1</span>, <span class="number">2</span>, <span class="number">7</span>]</span><br></pre></td></tr></table></div></figure><p>步长可以是负数，改变方向（从尾部开始向左走）：</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">list1[::-<span class="number">2</span>]</span><br><span class="line">[<span class="number">8</span>, <span class="number">9</span>, <span class="number">3</span>]</span><br></pre></td></tr></table></div></figure>        <h3 id="8-可以利用分片完成列表的拷贝-list2-list1-，那事实上可不可以直接写成-list2-list1-更加简洁呢？"   >          <a href="#8-可以利用分片完成列表的拷贝-list2-list1-，那事实上可不可以直接写成-list2-list1-更加简洁呢？" class="heading-link"><i class="fas fa-link"></i></a><a href="#8-可以利用分片完成列表的拷贝-list2-list1-，那事实上可不可以直接写成-list2-list1-更加简洁呢？" class="headerlink" title="8. 可以利用分片完成列表的拷贝 list2 &#x3D; list1[:]，那事实上可不可以直接写成 list2 &#x3D; list1 更加简洁呢？"></a>8. 可以利用分片完成列表的拷贝 list2 &#x3D; list1[:]，那事实上可不可以直接写成 list2 &#x3D; list1 更加简洁呢？</h3>      <p>千万不可以！</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span>list1 = [<span class="number">1</span>, <span class="number">3</span>, <span class="number">2</span>, <span class="number">9</span>, <span class="number">7</span>, <span class="number">8</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>list2 = list1[:]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>list2</span><br><span class="line">[<span class="number">1</span>, <span class="number">3</span>, <span class="number">2</span>, <span class="number">9</span>, <span class="number">7</span>, <span class="number">8</span>]</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>list3 = list1</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>list3</span><br><span class="line">[<span class="number">1</span>, <span class="number">3</span>, <span class="number">2</span>, <span class="number">9</span>, <span class="number">7</span>, <span class="number">8</span>]</span><br></pre></td></tr></table></div></figure><p>如果对list1进行排序，list1变为[1，2，3，7，8，9]</p>        <h5 id="list2不变，而输出list3会发现，它也被排序了"   >          <a href="#list2不变，而输出list3会发现，它也被排序了" class="heading-link"><i class="fas fa-link"></i></a><a href="#list2不变，而输出list3会发现，它也被排序了" class="headerlink" title="list2不变，而输出list3会发现，它也被排序了"></a>list2不变，而输出list3会发现，它也被排序了</h5>      <p><img src="/images/image-20250909084404231.png" alt="image-20250909084404231"></p>        <h3 id="9-列表还有两个内置方法没给大家介绍，不过聪明的你应该可以自己摸索使用的门道吧：copy-和-clear"   >          <a href="#9-列表还有两个内置方法没给大家介绍，不过聪明的你应该可以自己摸索使用的门道吧：copy-和-clear" class="heading-link"><i class="fas fa-link"></i></a><a href="#9-列表还有两个内置方法没给大家介绍，不过聪明的你应该可以自己摸索使用的门道吧：copy-和-clear" class="headerlink" title="9.列表还有两个内置方法没给大家介绍，不过聪明的你应该可以自己摸索使用的门道吧：copy() 和 clear()"></a>9.列表还有两个内置方法没给大家介绍，不过聪明的你应该可以自己摸索使用的门道吧：copy() 和 clear()</h3>      <p>copy() 方法跟使用切片拷贝是一样的：</p><blockquote><blockquote><blockquote><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&gt;&gt;&gt; list2 = list1.copy()</span><br><span class="line">&gt;&gt;&gt; list2</span><br><span class="line">&gt;&gt;&gt; [1, [1, 2, [&#x27;小甲鱼&#x27;]], 3, 5, 8, 13, 18]</span><br><span class="line"></span><br><span class="line">**clear() 方法用于清空列表的元素，但要注意，清空完后列表仍然还在哦，只是变成一个空列表。**</span><br><span class="line">list2.clear()</span><br><span class="line">list2</span><br><span class="line">[]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### 10.列表推导式/列表解析</span><br><span class="line"></span><br></pre></td></tr></table></div></figure><p> [i*i for i in range(10)]<br>输出 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]</p></blockquote></blockquote></blockquote><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">### 11.补充列表的一些内置函数BIF</span><br><span class="line"></span><br><span class="line">list.count(a)：列表list中元素a出现的次数；</span><br><span class="line"></span><br><span class="line">list.index(a)：列表list中元素a第一次出现的索引号</span><br><span class="line"></span><br><span class="line">list.index(a，b，c)：列表list中元素a在索引范围[b，c]中第一次出现的索引号</span><br><span class="line"></span><br><span class="line">list.reverse()：翻转list</span><br><span class="line"></span><br><span class="line">list.sort()：排序，默认从小到大排序</span><br><span class="line"></span><br><span class="line">list.sort(reverse=True)：从大到小排序</span><br><span class="line"></span><br><span class="line">### 12.元组和列表的最大区别是什么？</span><br><span class="line"></span><br><span class="line">元组不可修改，而列表可以修改。所以要求数据不能修改时使用元组，频繁要求修改数据时使用列表</span><br><span class="line"></span><br><span class="line">当然格式也有区别</span><br><span class="line"></span><br><span class="line">元组是（）括号</span><br><span class="line"></span><br><span class="line">列表是[]</span><br><span class="line"></span><br><span class="line">### 13.元组可以使用的方法有哪些</span><br><span class="line"></span><br><span class="line">count():计算并返回指定函数的数量</span><br><span class="line"></span><br><span class="line">index():寻找并返回参数的索引值</span><br><span class="line"></span><br><span class="line">### 13.创建一个元组，什么情况下逗号和小括号必须同时存在，缺一不可？</span><br><span class="line"></span><br><span class="line">在拼接只有一个元素的元组的时候，例如我们课上举的例题：</span><br><span class="line"></span><br><span class="line">&gt;&gt;&gt; temp = (‘小甲鱼’, ‘黑夜’, ‘迷途’, ‘小布丁’)</span><br><span class="line">###### 如果我想在“黑夜”和“迷途”之间插入“怡静”，我们应该：</span><br><span class="line">&gt;&gt;&gt; temp = temp[:2] + (‘怡静’,) + temp[2:]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### 14.x, y, z = 1, 2, 3 请问x, y, z是元组吗？</span><br><span class="line"></span><br><span class="line">**&lt;u&gt;所有的多对象的、逗号分隔的、没有明确用符号定义的这些集合默认的类型都是元组&lt;/u&gt;**，自己在IDLE中键入以下代码，并体会一下：</span><br><span class="line"></span><br><span class="line">&gt;&gt;&gt; ```python</span><br><span class="line">&gt;&gt;&gt; x, y, z = 1, 2, 3</span><br><span class="line">&gt;&gt;&gt; type(x)</span><br><span class="line">&gt;&gt;&gt; &lt;class &#x27;int&#x27;&gt;</span><br><span class="line">&gt;&gt;&gt; h = x, y, z</span><br><span class="line">&gt;&gt;&gt; type(h)</span><br><span class="line">&gt;&gt;&gt; &lt;class &#x27;tuple&#x27;&gt;</span><br></pre></td></tr></table></div></figure>        <h3 id="15-file1-open-‘C-windows-temp-readme-txt’-‘r’-表示以只读方式打开“C-windows-temp-readme-txt”这个文本文件，但事实上这个语句会报错，知道为什么吗？你会如何修改？"   >          <a href="#15-file1-open-‘C-windows-temp-readme-txt’-‘r’-表示以只读方式打开“C-windows-temp-readme-txt”这个文本文件，但事实上这个语句会报错，知道为什么吗？你会如何修改？" class="heading-link"><i class="fas fa-link"></i></a><a href="#15-file1-open-‘C-windows-temp-readme-txt’-‘r’-表示以只读方式打开“C-windows-temp-readme-txt”这个文本文件，但事实上这个语句会报错，知道为什么吗？你会如何修改？" class="headerlink" title="15.file1 &#x3D; open(‘C:\windows\temp\readme.txt’, ‘r’) 表示以只读方式打开“C:\windows\temp\readme.txt”这个文本文件，但事实上这个语句会报错，知道为什么吗？你会如何修改？"></a>15.file1 &#x3D; open(‘C:\windows\temp\readme.txt’, ‘r’) 表示以只读方式打开“C:\windows\temp\readme.txt”这个文本文件，但事实上这个语句会报错，知道为什么吗？你会如何修改？</h3>      <p>会报错是因为在字符串中，我们约<strong>定“\t”和“\r”分别表示“横向制表符（TAB）”和“回车符</strong>”（详见：<span class="exturl"><a class="exturl__link"   href="http://bbs.fishc.com/thread-92997-1-1.html%EF%BC%89%EF%BC%8C%E5%9B%A0%E6%AD%A4%E5%B9%B6%E4%B8%8D%E4%BC%9A%E6%8C%89%E7%85%A7%E6%88%91%E4%BB%AC%E8%AE%A1%E5%88%92%E7%9A%84%E8%B7%AF%E5%BE%84%E5%8E%BB%E6%89%93%E5%BC%80%E6%96%87%E4%BB%B6%E3%80%82" >http://bbs.fishc.com/thread-92997-1-1.html），因此并不会按照我们计划的路径去打开文件。</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p><p>Python 为我们铺好了解决的道路，只需要使用原始字符串操作符（R或r）即可：</p><blockquote><blockquote><blockquote><p>file1 &#x3D; open(r’C:\windows\temp\readme.txt’, ‘r’)</p></blockquote></blockquote></blockquote>        <h3 id="16-写一个检查密码安全性的代码"   >          <a href="#16-写一个检查密码安全性的代码" class="heading-link"><i class="fas fa-link"></i></a><a href="#16-写一个检查密码安全性的代码" class="headerlink" title="16.写一个检查密码安全性的代码"></a>16.写一个检查密码安全性的代码</h3>      <p><img src="/images/image-20250909095256638.png" alt="image-20250909095256638"></p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br></pre></td><td class="code"><pre><span class="line">symbols = <span class="string">r&#x27;&#x27;&#x27;`!@#$%^&amp;*()_+-=/*&#123;&#125;[]\|&#x27;&quot;;:/?,.&lt;&gt;&#x27;&#x27;&#x27;</span></span><br><span class="line">chars = <span class="string">&#x27;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ&#x27;</span></span><br><span class="line">nums = <span class="string">&#x27;0123456789&#x27;</span></span><br><span class="line"></span><br><span class="line">passwd = <span class="built_in">input</span>(<span class="string">&#x27;请输入需要检查的密码组合：&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 判断长度</span></span><br><span class="line"></span><br><span class="line">length = <span class="built_in">len</span>(passwd)</span><br><span class="line"></span><br><span class="line"><span class="keyword">while</span> (passwd.isspace() <span class="keyword">or</span> length == <span class="number">0</span>) :</span><br><span class="line">    passwd = <span class="built_in">input</span>(<span class="string">&quot;您输入的密码为空（或空格），请重新输入：&quot;</span>)</span><br><span class="line">    length = <span class="built_in">len</span>(passwd)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> length &lt;= <span class="number">8</span>:</span><br><span class="line">    flag_len = <span class="number">1</span></span><br><span class="line"><span class="keyword">elif</span> <span class="number">8</span> &lt; length &lt; <span class="number">16</span>:</span><br><span class="line">    flag_len = <span class="number">2</span></span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">    flag_len = <span class="number">3</span></span><br><span class="line"></span><br><span class="line">flag_con = <span class="number">0</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 判断是否包含特殊字符</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> each <span class="keyword">in</span> passwd:</span><br><span class="line">    <span class="keyword">if</span> each <span class="keyword">in</span> symbols:</span><br><span class="line">        flag_con += <span class="number">1</span></span><br><span class="line">        <span class="keyword">break</span></span><br><span class="line">    </span><br><span class="line"></span><br><span class="line"><span class="comment"># 判断是否包含字母</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> each <span class="keyword">in</span> passwd:</span><br><span class="line">    <span class="keyword">if</span> each <span class="keyword">in</span> chars:</span><br><span class="line">        flag_con += <span class="number">1</span></span><br><span class="line">        <span class="keyword">break</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 判断是否包含数字</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> each <span class="keyword">in</span> passwd:</span><br><span class="line">    <span class="keyword">if</span> each <span class="keyword">in</span> nums:</span><br><span class="line">        flag_con += <span class="number">1</span></span><br><span class="line">        <span class="keyword">break</span>    </span><br><span class="line"></span><br><span class="line"><span class="comment"># 打印结果</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">while</span> <span class="number">1</span> :</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;您的密码安全级别评定为：&quot;</span>, end=<span class="string">&#x27;&#x27;</span>)</span><br><span class="line">    <span class="keyword">if</span> flag_len == <span class="number">1</span> <span class="keyword">or</span> flag_con == <span class="number">1</span> :</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;低&quot;</span>)</span><br><span class="line">    <span class="keyword">elif</span> flag_len == <span class="number">3</span> <span class="keyword">and</span> flag_con == <span class="number">3</span> <span class="keyword">and</span> (passwd[<span class="number">0</span>] <span class="keyword">in</span> chars):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;高&quot;</span>)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;请继续保持&quot;</span>)</span><br><span class="line">        <span class="keyword">break</span></span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;中&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;请按以下方式提升您的密码安全级别：\n\</span></span><br><span class="line"><span class="string">    \t1. 密码必须由数字、字母及特殊字符三种组合\n\</span></span><br><span class="line"><span class="string">    \t2. 密码只能由字母开头\n\</span></span><br><span class="line"><span class="string">    \t3. 密码长度不能低于16位&quot;</span>)</span><br><span class="line">    <span class="keyword">break</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></div></figure>        <h3 id="17-字符串常用方法"   >          <a href="#17-字符串常用方法" class="heading-link"><i class="fas fa-link"></i></a><a href="#17-字符串常用方法" class="headerlink" title="17.字符串常用方法"></a>17.字符串常用方法</h3>      <div class="table-container"><table><thead><tr><th>capitalize()</th><th>把字符串的第一个字母修改为大写</th></tr></thead><tbody><tr><td>casefold()</td><td>把整个字符串的内容转为小写</td></tr><tr><td>center(width)</td><td>把字符串居中并用空格填充至长度width的新字符串</td></tr><tr><td>count(sub,start,end)</td><td>统计字符串sub在索引start到end（不包括end）中出现了几次</td></tr><tr><td>find(sub,start,end)</td><td>检查sub字符串是否被包含，有则返回索引值，否则返回-1</td></tr><tr><td>index(sub,start,end)</td><td>和find方法一致，但是如果sub不在指定字符串中会返回异常</td></tr><tr><td>isalnum()</td><td>如果字符串至少有一个字符且字符都是数字或字母则返回True，否则返回false</td></tr><tr><td>isalpha（）</td><td>如果字符串至少有一个字符且字符都是字母则返回True，否则返回false</td></tr><tr><td>isdigit（）</td><td>如果字符串中只包含数字则返回true，否则false</td></tr><tr><td>isdemical()</td><td>十进制数</td></tr><tr><td>islower()</td><td>如果字符串中至少包含一个区分大小写的字符，并且这些字符都是小写，则返回 True，否则返回 False。</td></tr><tr><td>isupper()</td><td>如果字符串中至少包含一个区分大小写的字符，并且这些字符都是大写，则返回 True，否则返回 False。</td></tr><tr><td>join(sub)</td><td>以字符串作为分隔符，插入到sub的所有字符间</td></tr><tr><td>ljuest(width)</td><td>返回一个左对齐的字符串，并使用空格填充</td></tr><tr><td>lower()</td><td>把大写字符转为小写</td></tr><tr><td>lstrip()</td><td>去掉字符串左边所有空格</td></tr><tr><td>replace(“old”,”new”,count)</td><td>把字符串中的 old 子字符串替换成 new 子字符串，如果 count 指定，则替换不超过 count 次。</td></tr><tr><td>translate(table)</td><td>根据 table 的规则（可以由 str.maketrans(‘a’, ‘b’) 定制）转换字符串中的字符。</td></tr><tr><td>zfill(width)</td><td>返回长度为 width 的字符串，原字符串右对齐，前边用 0 填充。</td></tr><tr><td>strip(chars)</td><td>删除字符串前边和后边所有的空格，chars 参数可以定制删除的字符，可选。</td></tr><tr><td>swapcase()</td><td>翻转大小写</td></tr><tr><td></td><td></td></tr><tr><td></td><td></td></tr><tr><td></td><td></td></tr><tr><td></td><td></td></tr><tr><td></td><td></td></tr><tr><td></td><td></td></tr><tr><td></td><td></td></tr><tr><td></td><td></td></tr><tr><td></td><td></td></tr></tbody></table></div>]]></content>
      
      
      <categories>
          
          <category> python学习 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> python </tag>
            
            <tag> 学习 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>爬虫理论入门</title>
      <link href="/2025/09/09/%E7%88%AC%E8%99%AB%E7%90%86%E8%AE%BA/"/>
      <url>/2025/09/09/%E7%88%AC%E8%99%AB%E7%90%86%E8%AE%BA/</url>
      
        <content type="html"><![CDATA[        <h3 id="1-什么是爬虫？"   >          <a href="#1-什么是爬虫？" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-什么是爬虫？" class="headerlink" title="1.什么是爬虫？"></a>1.什么是爬虫？</h3>      <p>爬虫顾名思义，就像一个在互联网这张大网上沿着链接不断爬行的虫子，不断获取它收集到的所有信息</p><p>它按照一定的规则，<strong>自动地抓取互联网信息的脚本或程序</strong></p>        <h3 id="2-爬虫的工作原理是什么？"   >          <a href="#2-爬虫的工作原理是什么？" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-爬虫的工作原理是什么？" class="headerlink" title="2.爬虫的工作原理是什么？"></a>2.爬虫的工作原理是什么？</h3>      <p>爬虫的本质其实是<strong>不断发送http请求</strong></p><p>那么如何发送http请求呢？</p><p>可以用python的<code>requests</code>库</p><p>只要我们获取到了URL(<strong>统一资源定位符</strong>，每个网页都有自己对应的唯一的URL)，就可以通过一些方法发送http请求</p><p>发送之后服务器就会收到我们的请求，向我们发出响应，为http响应，它通常包含<strong>状态码，头部信息，内容主体</strong></p><p>通过服务器的响应，我们可以储存和分析数据，这里由于我们爬取的目的不同，做法也不尽相同。</p>        <h3 id="3-什么是http协议？"   >          <a href="#3-什么是http协议？" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-什么是http协议？" class="headerlink" title="3.什么是http协议？"></a>3.什么是http协议？</h3>      <p>我们经常可以看到http协议这个词，那么http到底是什么？</p><p>如果你学过计算机导论或者计算机网络，对这个名词一定不陌生</p><p><strong>HTTP全称 “<code>HyperText Transfer Protoca</code>”<strong>即</strong>超文本传输协议</strong>，它是位于<strong>应用层</strong>的一种从<strong>客户到服务器</strong>的协议。</p><p>一个完整的Http请求包含三个部分</p><p><strong>请求行，请求头，请求体</strong></p>        <h3 id="4-请求行-Request-Line"   >          <a href="#4-请求行-Request-Line" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-请求行-Request-Line" class="headerlink" title="4.请求行(Request Line)"></a>4.请求行(Request Line)</h3>      <p>一个完整的请求行长这样 </p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">“GET /index.html HTTP/1.1”</span><br></pre></td></tr></table></div></figure><ul><li><p><strong>方法</strong>: GET（获取资源）、POST（提交数据）、PUT、DELETE等</p></li><li><p><strong>路径</strong>: &#x2F;index.html（请求的资源路径）（有时候除了资源路径，我们还可以设置查询参数来查询信息，不同信息用&amp;分割，查询参数通常在问号后面），比如</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">www.douban.com/movie/top250?start=75&amp;filter=unwatched</span><br></pre></td></tr></table></div></figure></li><li><p><strong>协议版本</strong>: HTTP&#x2F;1.1</p></li></ul>        <h3 id="5-请求方法有哪些？"   >          <a href="#5-请求方法有哪些？" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-请求方法有哪些？" class="headerlink" title="5.请求方法有哪些？"></a>5.请求方法有哪些？</h3>      <div class="table-container"><table><thead><tr><th>方法</th><th>描述</th></tr></thead><tbody><tr><td>GET</td><td>从服务器<strong>获取资源</strong>，不能更改数据，只能请求</td></tr><tr><td>POST</td><td>向服务器发送数据，<strong>创建新资源</strong>。可以提交表单，文件（发送的数据包含在请求体中）</td></tr><tr><td>PUT</td><td>向服务器发送数据，<strong>更新现有资源（修改资源）</strong>。不存在则创新。与POST的区别是，PUT 通常是幂等的，即多次执行相同的 PUT 请求不会产生不同的结果。</td></tr><tr><td>DELETE</td><td>从服务器中<strong>删除指定资源</strong>，请求中包含要删除的资源符</td></tr><tr><td>PATCH</td><td>部分<strong>修改资源</strong>，与PUT类似，但是PATCH不替换整个资源，只修改部分数据</td></tr><tr><td>HEAD</td><td>类似于GET,服务器<strong>只返回响应头部</strong>，不返回实际数据</td></tr><tr><td>OPTIONS</td><td>返回服务器支持的<strong>HTTP方法</strong>，用于检查服务支持哪些请求方法，通常用于跨域资源共享的预检请求</td></tr><tr><td>TRACE</td><td><strong>回显服务器收到的请求</strong>，主要用于诊断。客户端可以查看请求在服务器中的处理路径。</td></tr><tr><td>CONNECTION</td><td>建立一个到服务器的隧道，通常用于 HTTPS 连接。客户端可以通过该隧道发送加密的数据。</td></tr></tbody></table></div>        <h3 id="6-请求头（Request-Headers）"   >          <a href="#6-请求头（Request-Headers）" class="heading-link"><i class="fas fa-link"></i></a><a href="#6-请求头（Request-Headers）" class="headerlink" title="6.请求头（Request Headers）"></a>6.请求头（Request Headers）</h3>      <p>它包含了关于客户端请求的附加信息，以<strong>键值对</strong>的形式传递给服务器</p><p> <strong>1.基础标识头 User-Agent</strong>(用户代理)</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36</span><br></pre></td></tr></table></div></figure><p>它告诉服务器，客户端的类型和版本</p><p><strong>爬虫重要性</strong>：⭐⭐⭐⭐⭐</p><p><strong>说明</strong>：服务器通过这个字段判断是浏览器还是爬虫。<strong>如果不设置或使用默认值，很容易被识别为爬虫</strong>。</p><p><code>Mozilla/5.0</code>其实是一个出于兼容性考虑而保留的“遗产”令牌，当时很多网站会检查User-Agent,如果是Mozilla就提供高级功能（框架），否则提供基础页面。为了能接收到最好的网页，现在几乎所有浏览器都自称是Mozilla以保持兼容。</p><p><code>Windows NT 10.0; Win64; x64</code>描述操作系统平台。</p><p>注意：由于 <code>User-Agent</code>字符串变得非常复杂、容易伪造，并且可能被用于<strong>指纹追踪</strong>用户，谷歌等公司正在推动一项名为 <strong><code>User-Agent Client Hints</code></strong> 的新标准来逐步取代它。新标准旨在让用户拥有更多隐私控制权，只在必要时向服务器提供特定的设备信息，而不是一次性全部发送。</p><p>2.<strong>主机（host）</strong></p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Host: cgyy.nenu.edu.cn</span><br></pre></td></tr></table></div></figure><p>它是HTTP&#x2F;1.1必需字段，可以<strong>指定请求的目标服务器域名</strong></p><p>3.<strong>内容协商头 Accept</strong></p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8</span><br></pre></td></tr></table></div></figure><p>告诉服务器，客户端能够处理哪些内容类型</p><p>常见值：</p><p>text&#x2F;html  HTML文档</p><p>application&#x2F;json  json数据</p><p>image&#x2F;*-  所有图片类型</p><p>4.<strong>可接受语言Accept-Language</strong></p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Accept-Language: zh-CN,zh;q=0.9,en;q=0.8</span><br></pre></td></tr></table></div></figure><ul><li><strong>作用</strong>：告诉服务器客户端的语言偏好</li><li><strong>爬虫重要性</strong>：⭐⭐⭐<ul><li><strong><code>zh-CN</code></strong>: 这是首选语言。<code>zh</code>代表中文，<code>-CN</code>是子标签，代表中国大陆地区使用的中文（简体中文）。</li><li><strong><code>zh;q=0.9</code></strong>: 这是次选语言。<code>zh</code>代表所有中文变体（如简体或繁体），如果没有 <code>zh-CN</code>，也可以用其他中文版本。<code>q=0.9</code>表示优先级权重是 0.9（范围 0-1，1 是最高）。</li><li><strong><code>en;q=0.8</code></strong>: 这是第三选择。<code>en</code>代表英语，优先级权重是 0.8。</li></ul></li></ul><p><strong>5.Accept-Encoding（可接受的编码）</strong></p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Accept-Encoding: gzip, deflate, br</span><br></pre></td></tr></table></div></figure><ul><li><strong>作用</strong>：告诉服务器客户端支持的压缩格式</li><li><strong>说明</strong>：服务器可能会返回压缩后的内容，需要解压</li></ul><ol start="6"><li><strong>连接管理头</strong></li></ol><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Connection: keep-alive</span><br></pre></td></tr></table></div></figure><ul><li><strong>作用</strong>：控制连接是否保持活跃</li><li><strong>常见值</strong>：<ul><li><code>keep-alive</code>- 保持连接</li><li><code>close</code>- 关闭连接</li></ul></li></ul><p><strong>7.缓存相关头If-Modified-Since</strong></p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">If-Modified-Since: Wed, 18 Sep 2025 01:00:00 GMT</span><br></pre></td></tr></table></div></figure><ul><li><strong>作用</strong>：如果资源在此时间后没有修改，返回304状态码</li></ul><p><strong>8. 认证和安全头</strong>Authorization（认证）</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...</span><br></pre></td></tr></table></div></figure><ul><li><strong>作用</strong>：包含认证凭证</li><li><strong>常见类型</strong>：<ul><li><code>Basic</code>- 基本认证</li><li><code>Bearer</code>- Token认证</li><li><code>Digest</code>- 摘要认证</li></ul></li></ul><p><strong>9.Cookie</strong></p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Cookie: session_id=abc123; user_token=xyz456</span><br></pre></td></tr></table></div></figure><ul><li><strong>作用</strong>：向服务器发送之前存储的Cookie</li><li><strong>爬虫重要性</strong>：⭐⭐⭐⭐⭐</li><li><strong>格式</strong>：<code>name=value</code>对，用分号分隔</li></ul><p><strong>10. 来源和引用头</strong>Referer（引用来源）</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Referer: https://cgyy.nenu.edu.cn/booking</span><br></pre></td></tr></table></div></figure><ul><li><strong>作用</strong>：告诉服务器当前请求是从哪个页面链接过来的</li><li><strong>爬虫重要性</strong>：⭐⭐⭐⭐</li><li><strong>注意</strong>：有些网站会检查Referer来防止盗链</li></ul>        <h4 id="Origin（来源）"   >          <a href="#Origin（来源）" class="heading-link"><i class="fas fa-link"></i></a><a href="#Origin（来源）" class="headerlink" title="Origin（来源）"></a>Origin（来源）</h4>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Origin: https://cgyy.nenu.edu.cn</span><br></pre></td></tr></table></div></figure><ul><li><strong>作用</strong>：表明请求的来源，用于CORS（跨域资源共享）</li></ul><p>这是一个爬虫常用请求头举例</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">headers = &#123;</span><br><span class="line">    <span class="string">&#x27;Host&#x27;</span>: <span class="string">&#x27;cgyy.nenu.edu.cn&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;Connection&#x27;</span>: <span class="string">&#x27;keep-alive&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;Accept&#x27;</span>: <span class="string">&#x27;*/*&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;Content-Type&#x27;</span>: <span class="string">&#x27;application/json&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;Cookie&#x27;</span>: <span class="string">&#x27;acw_tc=ac11000117581585555872261e488f4d176bbf7b6670727206b5636e12a130&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;Origin&#x27;</span>: <span class="string">&#x27;https://cgyy.nenu.edu.cn&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;User-Agent&#x27;</span>: <span class="string">&#x27;Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;token&#x27;</span>: <span class="string">&#x27;eyJhbGciOiJSUzI1NiJ9...&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;Referer&#x27;</span>: <span class="string">&#x27;https://cgyy.nenu.edu.cn/&#x27;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure><p>除了这一种方法，还可以使用Session对象</p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">session = requests.Session()</span><br><span class="line">session.headers.update(&#123;</span><br><span class="line">    <span class="string">&#x27;User-Agent&#x27;</span>: <span class="string">&#x27;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;Accept-Language&#x27;</span>: <span class="string">&#x27;zh-CN,zh;q=0.9&#x27;</span></span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">response = session.get(<span class="string">&#x27;https://example.com&#x27;</span>)</span><br></pre></td></tr></table></div></figure><p>后续我会对这两种的使用进行扩展说明（其实是我觉得我现在水平还不够）</p>        <h3 id="7-如何获取查看请求头？"   >          <a href="#7-如何获取查看请求头？" class="heading-link"><i class="fas fa-link"></i></a><a href="#7-如何获取查看请求头？" class="headerlink" title="7.如何获取查看请求头？"></a>7.如何获取查看请求头？</h3>      <p><strong>浏览器开发者工具查看</strong></p><ol><li>按F12打开开发者工具</li><li>切换到Network（网络）标签</li><li>刷新页面或触发请求</li><li>点击具体请求，查看Headers标签</li></ol><p><strong>Python中查看响应头</strong></p><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"></span><br><span class="line">response = requests.get(<span class="string">&#x27;https://httpbin.org/headers&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;请求头:&quot;</span>, response.request.headers)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;响应头:&quot;</span>, response.headers)</span><br></pre></td></tr></table></div></figure><p>注意！网站通常会检测以下头信息来识别爬虫：</p><ol><li><strong>User-Agent</strong>：非浏览器或默认Python UA</li><li><strong>Accept</strong>、<strong>Accept-Language</strong>：缺失或不合理</li><li><strong>Referer</strong>：缺失或不符合正常浏览流程</li><li><strong>Cookie</strong>：缺失或异常</li><li><strong>其他头字段</strong>：如<code>Sec-</code>开头的安全头</li></ol>        <h3 id="8-HTTP状态码"   >          <a href="#8-HTTP状态码" class="heading-link"><i class="fas fa-link"></i></a><a href="#8-HTTP状态码" class="headerlink" title="8.HTTP状态码"></a>8.HTTP状态码</h3>      <p>1开头的状态码（信息类）：表示请求正在处理</p><p>2开头的状态码（成功）：请求正常处理</p><p>3开头的状态码（重定向）：需要后续操作才能完成请求</p><p>4开头的状态码（客户端错误）：请求包含语法错误或无法完成</p><p>5开头的状态码（服务器错误）：服务器处理请求过程中发生错误了</p><p><strong>常见状态码</strong></p><div class="table-container"><table><thead><tr><th>200</th><th>请求成功</th></tr></thead><tbody><tr><td>301</td><td>资源被永久移动到新地址</td></tr><tr><td>400</td><td>客户端不能被服务器理解</td></tr><tr><td>401</td><td>客户未经授权</td></tr><tr><td>403</td><td>服务器拒绝提供服务</td></tr><tr><td>404</td><td>请求资源不存在</td></tr><tr><td>500</td><td>服务器发生不可预期的错误</td></tr><tr><td>503</td><td>服务器不能处理客户端请求</td></tr></tbody></table></div><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"></span><br><span class="line">response = requests.get(<span class="string">&quot;URL&quot;</span>)</span><br><span class="line"><span class="keyword">if</span> response.ok:</span><br><span class="line">    <span class="built_in">print</span>(response.text)</span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;请求失败&quot;</span>)</span><br></pre></td></tr></table></div></figure>]]></content>
      
      
      <categories>
          
          <category> 爬虫 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> pythob </tag>
            
            <tag> 爬虫 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>网站食用方法（推荐阅读！）</title>
      <link href="/2025/09/08/%E7%BD%91%E7%AB%99%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8D%97/"/>
      <url>/2025/09/08/%E7%BD%91%E7%AB%99%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8D%97/</url>
      
        <content type="html"><![CDATA[        <h3 id="关于为什么写这个网站"   >          <a href="#关于为什么写这个网站" class="heading-link"><i class="fas fa-link"></i></a><a href="#关于为什么写这个网站" class="headerlink" title="关于为什么写这个网站"></a>关于为什么写这个网站</h3>      <p>部署一个自己的网站实在不是一件简单的事，但也实在是一个很酷的事。</p><p>互联网，千亿万亿的连接好像一张星系图。倘若有自己的一个网站，那么在万千星辰中，竟然有一颗是独独属于你的。</p><p><img src="/images/star.jpg" alt="star"></p><p>有些旅人也许会因为一些机缘巧合落到这颗星球上，它的一切，或荒芜，或苍翠。或单调，或繁杂。都被放在你眼前，等待着探索。它会有哪些隐秘的角落，有哪些惊艳的景色。时光在它身上留下了怎样的痕迹……</p><p><strong>这应该，也是我学计算机的初心之一吧</strong></p><p>我很少当面表达自己，我喜欢书信，文字，这些能让我慢慢思考如何表达，给我独自剖开内心的安全感。有些话总不好宣之于口，听起来也许轻浮，也许沉重。但纸墨好似有某种魔力。</p><p><strong>纸那样轻，却能承起太多深重的感情。墨那样轻，却足以将情感诉说的深沉。</strong></p><p>个人博客对我来说也是如此，就像你打开之后会看到的那一句话</p><p><strong>“欢迎来到我的精神世界”</strong>。</p><p>在这里我变成了造物主，所有的一切都是我敲下的代码创造的。朋友，我不知道你是否能理解这种美妙，但我想人们对于“唯一”，“专属”这类词总是情有独钟的。这是独属于我的天地。</p><p>人们都说互联网时代，信息爆炸，再有热度的事也会一晃而过。科技发展的洪流好像要把人吞没。</p><p>但是我也庆幸，因为它的记忆是永存的。它不像人脑，总是会优先记住当下的，重要的。对于存储器而言，<strong>你的每一段记忆都是平等的</strong>，**它们不分轻重缓急。**它们一直会在。</p><p>是啊，本该如此，我的记忆为何要不平等呢，我为何要遗忘一些事呢？</p><p><strong>这就是第二个原因，记录。</strong></p><p>将来的我会变成什么样，会有怎样的未来，拥有怎样的生活？我给不了答案，也无需一个答案。</p><p>我只需走好我现在要迈出的这一步，也带着我曾经走的每一步路的信念就好。</p><p>我有很多想记录的事，这大概是源于我有很多珍惜的事。我的朋友，我的学习，我的文字，乃至我的痛苦与释然。</p><p>当然俗气一点的说，也可以勉励自己热爱生活，充实的度过每一天。网站会无声的告诉你“读书笔记几天没有更新啦”。</p><p>每次更新网站的时候，我内心都有一个声音</p><p><strong>你看，你一直在往前走</strong></p><p><img src="/images/20200228102720_wcnmi.jpg" alt="可爱表情包 - 堆糖，美图壁纸兴趣社区"></p>        <h3 id="你能在这个网站看到什么"   >          <a href="#你能在这个网站看到什么" class="heading-link"><i class="fas fa-link"></i></a><a href="#你能在这个网站看到什么" class="headerlink" title="你能在这个网站看到什么"></a>你能在这个网站看到什么</h3>      <p>标题栏的<strong>文章</strong>板块，你可以看到我写的所有东西。有些杂乱。</p><p>这有我的<strong>学习笔记</strong>，<strong>乱七八糟的感想</strong>，<strong>诗歌</strong>，<strong>作文</strong>等等等。</p><p>学习方面，我最近主要更新的应该是<strong>python</strong>，<strong>爬虫</strong>，<strong>数据库</strong>，<strong>算法</strong>类。后面也许会更新<strong>机器学习</strong>（待研究的有兴趣的领域）。</p><p>读书方面，后续也许有我分享的<strong>书单</strong>（我会附上电子文件），喜欢的<strong>句子</strong>，<strong>诗文</strong>。</p><p>创作方面应该就是我的<strong>读后感</strong>，<strong>诗歌</strong>，<strong>文章</strong>。</p><p>你可以在<strong>分类</strong>板块选择你感兴趣的分类探索。（也许你会在某些隐秘的角落发现精神共鸣，那么恭喜你多了一份触动，也恭喜我在看不见的地方打动了一个人某一刻。）</p><p>然后就是<strong>友链</strong>板块。这像一个传送阵，可以传送到不同星球。是的，我的有些朋友们也有他们自己的博客。如果你也有的话，可以在<strong>评论区</strong>留下你的网站，或者发送到邮箱<span class="exturl"><a class="exturl__link"   href="mailto:&#x32;&#x39;&#x38;&#x35;&#x37;&#50;&#53;&#x38;&#x36;&#x36;&#64;&#113;&#x71;&#x2e;&#x63;&#111;&#x6d;" >2985725866@qq.com</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p><p>最后就是相册啦，这个板块没有想好。可能后面放点照片吧。也许会设置加密，如果你回答对问题就可以看！</p><p><img src="/images/OIP-C.webp" alt="盘点女生用的可爱的表情包 - 抖音"></p>]]></content>
      
      
      <categories>
          
          <category> 创作 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 博客 </tag>
            
            <tag> 写作 </tag>
            
            <tag> Hexo </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>python前言</title>
      <link href="/2025/09/08/py%E5%89%8D%E8%A8%80/"/>
      <url>/2025/09/08/py%E5%89%8D%E8%A8%80/</url>
      
        <content type="html"><![CDATA[        <h3 id="1-什么是BIF？"   >          <a href="#1-什么是BIF？" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-什么是BIF？" class="headerlink" title="1.什么是BIF？"></a>1.<strong>什么是BIF？</strong></h3>      <p>BIF 就是 Built-in Functions，内置函数</p>        <h3 id="2-python中的变量名不能以数字开头"   >          <a href="#2-python中的变量名不能以数字开头" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-python中的变量名不能以数字开头" class="headerlink" title="2.python中的变量名不能以数字开头"></a>2.python中的变量名不能以数字开头</h3>              <h3 id="3"   >          <a href="#3" class="heading-link"><i class="fas fa-link"></i></a><a href="#3" class="headerlink" title="3."></a>3.</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">a=<span class="number">1</span></span><br><span class="line">b=<span class="string">&#x27;1&#x27;</span></span><br><span class="line">a=b</span><br><span class="line"><span class="built_in">print</span>(a)</span><br></pre></td></tr></table></div></figure><p>会输出1，没有单引号，因为它用print打印</p>        <h3 id="4-除了使用反斜杠（-）进行字符转义，还有什么方法可以打印：Let’s-go-这个字符串？"   >          <a href="#4-除了使用反斜杠（-）进行字符转义，还有什么方法可以打印：Let’s-go-这个字符串？" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-除了使用反斜杠（-）进行字符转义，还有什么方法可以打印：Let’s-go-这个字符串？" class="headerlink" title="4. 除了使用反斜杠（\）进行字符转义，还有什么方法可以打印：Let’s go! 这个字符串？"></a><strong>4. 除了使用反斜杠（\）进行字符转义，还有什么方法可以打印：Let’s go! 这个字符串？</strong></h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">print</span>(<span class="string">&quot;Let&#x27;s go!&quot;</span>)  *<span class="comment"># 双引号内单引号无需转义*</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;&#x27;&#x27;Let&#x27;s go!&#x27;&#x27;&#x27;</span>)  *<span class="comment"># 三单引号* print(&quot;&quot;&quot;Let&#x27;s go!&quot;&quot;&quot;)  *# 三双引号*</span></span><br></pre></td></tr></table></div></figure>        <h3 id="5-如果非要在原始字符串结尾输入反斜杠，可以如何灵活处理？"   >          <a href="#5-如果非要在原始字符串结尾输入反斜杠，可以如何灵活处理？" class="heading-link"><i class="fas fa-link"></i></a><a href="#5-如果非要在原始字符串结尾输入反斜杠，可以如何灵活处理？" class="headerlink" title="5. 如果非要在原始字符串结尾输入反斜杠，可以如何灵活处理？"></a><strong>5. 如果非要在原始字符串结尾输入反斜杠，可以如何灵活处理？</strong></h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">*<span class="comment"># 在原始字符串外手动转义* </span></span><br><span class="line"></span><br><span class="line">path = <span class="string">r&#x27;C:\Users\Documents&#x27;</span><span class="string">&#x27;\\&#x27;</span>  *<span class="comment"># 注意两字符串间无空格* </span></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(path)  *<span class="comment"># 输出: C:\Users\Documents\</span></span><br><span class="line"></span><br><span class="line">*<span class="comment"># 将结尾反斜杠单独用普通字符串拼接* </span></span><br><span class="line"></span><br><span class="line">path = <span class="string">r&#x27;C:\Users\Documents&#x27;</span> + <span class="string">&#x27;\\&#x27;</span></span><br><span class="line"></span><br><span class="line"> <span class="built_in">print</span>(path)  <span class="comment"># 输出: C:\Users\Documents\</span></span><br></pre></td></tr></table></div></figure>        <h3 id="6-如果输出格式复杂的空行多空格多的文本怎么办？"   >          <a href="#6-如果输出格式复杂的空行多空格多的文本怎么办？" class="heading-link"><i class="fas fa-link"></i></a><a href="#6-如果输出格式复杂的空行多空格多的文本怎么办？" class="headerlink" title="6.如果输出格式复杂的空行多空格多的文本怎么办？"></a>6.如果输出格式复杂的空行多空格多的文本怎么办？</h3>              <h4 id="三重引号字符串‘’‘-xxx-‘’’"   >          <a href="#三重引号字符串‘’‘-xxx-‘’’" class="heading-link"><i class="fas fa-link"></i></a><a href="#三重引号字符串‘’‘-xxx-‘’’" class="headerlink" title="三重引号字符串‘’‘  xxx ‘’’"></a>三重引号字符串‘’‘  xxx ‘’’</h4>      <p>如果希望得到一个跨越多行的字符串，我们就可以使用三重引号字符串，这里的三重引号可以是三个单引号也可以是三个双引号。</p><p>&gt;&gt;&gt; str &#x3D; “””轻轻的我走了，</p><p>正如我轻轻的来；</p><p>我轻轻的招手，</p><p>作别西天的云彩。…</p><p>“””</p>        <h3 id="7-Python3-中，一行可以书写多个语句吗？"   >          <a href="#7-Python3-中，一行可以书写多个语句吗？" class="heading-link"><i class="fas fa-link"></i></a><a href="#7-Python3-中，一行可以书写多个语句吗？" class="headerlink" title="7. Python3 中，一行可以书写多个语句吗？"></a>7. Python3 中，一行可以书写多个语句吗？</h3>      <p>可以，语句之间用分号隔开即可，不妨试试：</p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">print(&#x27;I love fishc&#x27;);print(&#x27;very much!&#x27;)</span><br></pre></td></tr></table></div></figure>        <h3 id="8-我们人类思维是习惯于“四舍五入”法，你有什么办法使得-int-按照“四舍五入”的方式取整吗？"   >          <a href="#8-我们人类思维是习惯于“四舍五入”法，你有什么办法使得-int-按照“四舍五入”的方式取整吗？" class="heading-link"><i class="fas fa-link"></i></a><a href="#8-我们人类思维是习惯于“四舍五入”法，你有什么办法使得-int-按照“四舍五入”的方式取整吗？" class="headerlink" title="8.我们人类思维是习惯于“四舍五入”法，你有什么办法使得 int() 按照“四舍五入”的方式取整吗？"></a>8.我们人类思维是习惯于“四舍五入”法，你有什么办法使得 int() 按照“四舍五入”的方式取整吗？</h3>      <p>5.4 “四舍五入”结果为：5，int(5.4+0.5) &#x3D;&#x3D; 5<br>5.6 “四舍五入”结果为：6，int(5.6+0.5) &#x3D;&#x3D; 6</p>        <h3 id="9-取得一个变量的类型，视频中介绍可以使用-type-和-isinstance-，你更倾向于使用哪个？"   >          <a href="#9-取得一个变量的类型，视频中介绍可以使用-type-和-isinstance-，你更倾向于使用哪个？" class="heading-link"><i class="fas fa-link"></i></a><a href="#9-取得一个变量的类型，视频中介绍可以使用-type-和-isinstance-，你更倾向于使用哪个？" class="headerlink" title="9. 取得一个变量的类型，视频中介绍可以使用 type() 和 isinstance()，你更倾向于使用哪个？"></a>9. 取得一个变量的类型，视频中介绍可以使用 type() 和 isinstance()，你更倾向于使用哪个？</h3>      <p>建议使用 isinstance()，因为它的返回结果比较直接，另外 type() 其实并没有你想象的那么简单，我们后边会讲到。</p>        <h5 id="🤔-为什么-isinstance-更胜一筹？"   >          <a href="#🤔-为什么-isinstance-更胜一筹？" class="heading-link"><i class="fas fa-link"></i></a><a href="#🤔-为什么-isinstance-更胜一筹？" class="headerlink" title="🤔 为什么 isinstance()更胜一筹？"></a>🤔 <strong>为什么 <code>isinstance()</code>更胜一筹？</strong></h5>              <h5 id="1-继承链检查能力（核心优势）"   >          <a href="#1-继承链检查能力（核心优势）" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-继承链检查能力（核心优势）" class="headerlink" title="1. 继承链检查能力（核心优势）"></a>1. <strong>继承链检查能力</strong>（核心优势）</h5>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">class Animal:</span><br><span class="line">    pass</span><br><span class="line"></span><br><span class="line">class Dog(Animal):</span><br><span class="line">    pass</span><br><span class="line"></span><br><span class="line">dog = Dog()</span><br><span class="line"></span><br><span class="line"># type() 的局限性</span><br><span class="line">print(type(dog) == Animal)  # False - 只检查精确类型</span><br><span class="line"></span><br><span class="line"># isinstance() 的智能检查</span><br><span class="line">print(isinstance(dog, Animal))  # True - 识别继承关系</span><br><span class="line">print(isinstance(dog, (Animal, Dog)))  # True - 支持多类型检查</span><br></pre></td></tr></table></div></figure>        <h5 id="2-多类型联合检查"   >          <a href="#2-多类型联合检查" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-多类型联合检查" class="headerlink" title="2. 多类型联合检查"></a>2. <strong>多类型联合检查</strong></h5>      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">def process_input(value):</span><br><span class="line">    if isinstance(value, (int, float, str)):</span><br><span class="line">        # 同时检查多种类型</span><br><span class="line">        return f&quot;Processing: &#123;value&#125;&quot;</span><br><span class="line">    raise TypeError(&quot;Invalid type&quot;)</span><br></pre></td></tr></table></div></figure>        <h3 id="10-Python-的-floor-除法现在使用-“-”-实现，那-3-0-2-0-您目测会显示什么内容呢？"   >          <a href="#10-Python-的-floor-除法现在使用-“-”-实现，那-3-0-2-0-您目测会显示什么内容呢？" class="heading-link"><i class="fas fa-link"></i></a><a href="#10-Python-的-floor-除法现在使用-“-”-实现，那-3-0-2-0-您目测会显示什么内容呢？" class="headerlink" title="10. Python 的 floor 除法现在使用 “&#x2F;&#x2F;” 实现，那 3.0 &#x2F;&#x2F; 2.0 您目测会显示什么内容呢？"></a>10. Python 的 floor 除法现在使用 “&#x2F;&#x2F;” 实现，那 3.0 &#x2F;&#x2F; 2.0 您目测会显示什么内容呢？</h3>      <p>Python 这里会义无反顾地执行 floor 除法原则，答案是：1.0</p>        <h3 id="11-请用最快速度说出答案：not-1-or-0-and-1-or-3-and-4-or-5-and-6-or-7-and-8-and-9"   >          <a href="#11-请用最快速度说出答案：not-1-or-0-and-1-or-3-and-4-or-5-and-6-or-7-and-8-and-9" class="heading-link"><i class="fas fa-link"></i></a><a href="#11-请用最快速度说出答案：not-1-or-0-and-1-or-3-and-4-or-5-and-6-or-7-and-8-and-9" class="headerlink" title="11.请用最快速度说出答案：not 1 or 0 and 1 or 3 and 4 or 5 and 6 or 7 and 8 and 9"></a>11.请用最快速度说出答案：not 1 or 0 and 1 or 3 and 4 or 5 and 6 or 7 and 8 and 9</h3>      <p>答案是：4</p><p>not or and 的优先级是不同的：not &gt; and &gt; or</p><p>我们按照优先级给它们加上括号：(not 1) or (0 and 1) or (3 and 4) or (5 and 6) or (7 and 8 and 9)<br>&#x3D;&#x3D; 0 or 0 or 4 or 6 or 9<br>&#x3D;&#x3D; 4</p><p>为什么是 4？提到的“短路逻辑”：3 and 4 &#x3D;&#x3D; 4，而 3 or 4 &#x3D;&#x3D; 3。<br>所以答案是：4</p>        <h3 id="12-假设有-x-1，y-2，z-3，请问如何快速将三个变量的值互相交换？"   >          <a href="#12-假设有-x-1，y-2，z-3，请问如何快速将三个变量的值互相交换？" class="heading-link"><i class="fas fa-link"></i></a><a href="#12-假设有-x-1，y-2，z-3，请问如何快速将三个变量的值互相交换？" class="headerlink" title="12. 假设有 x &#x3D; 1，y &#x3D; 2，z &#x3D; 3，请问如何快速将三个变量的值互相交换？"></a>12. 假设有 x &#x3D; 1，y &#x3D; 2，z &#x3D; 3，请问如何快速将三个变量的值互相交换？</h3>      <p>x, y, z &#x3D; z, y, x</p>        <h3 id="13-猜猜-x-y-and-x-or-y-0-实现什么样的功能"   >          <a href="#13-猜猜-x-y-and-x-or-y-0-实现什么样的功能" class="heading-link"><i class="fas fa-link"></i></a><a href="#13-猜猜-x-y-and-x-or-y-0-实现什么样的功能" class="headerlink" title="13. 猜猜 (x &lt; y and [x] or [y])[0] 实现什么样的功能"></a>13. 猜猜 (x &lt; y and [x] or [y])[0] 实现什么样的功能</h3>      <p>即：<strong>返回 <code>x</code>和 <code>y</code>中的较小值</strong>（类似 <code>min(x, y)</code>的基础版）</p><hr>        <h3 id="🔍-分步拆解"   >          <a href="#🔍-分步拆解" class="heading-link"><i class="fas fa-link"></i></a><a href="#🔍-分步拆解" class="headerlink" title="🔍 分步拆解"></a>🔍 <strong>分步拆解</strong></h3>      <p>假设 <code>x = 3</code>, <code>y = 5</code>：</p><ol><li><ol><li></li></ol><p><strong>第一步：<code>x &lt; y</code>判断</strong></p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">3 &lt; 5 → True</span><br></pre></td></tr></table></div></figure></li><li><ol start="2"><li></li></ol><p><strong>第二步：<code>and [x]</code></strong></p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">True and [3] → [3]  # and操作返回最后一个真值</span><br></pre></td></tr></table></div></figure></li><li><ol start="3"><li></li></ol><p><strong>第三步：<code>or [y]</code></strong></p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[3] or [5] → [3]  # or操作在左值为真时短路返回</span><br></pre></td></tr></table></div></figure></li><li><ol start="4"><li></li></ol><p><strong>第四步：取列表首元素</strong></p><figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[3][0] → 3</span><br></pre></td></tr></table></div></figure></li></ol>        <h3 id="14-请将以下代码修改为三元操作符实现："   >          <a href="#14-请将以下代码修改为三元操作符实现：" class="heading-link"><i class="fas fa-link"></i></a><a href="#14-请将以下代码修改为三元操作符实现：" class="headerlink" title="14.请将以下代码修改为三元操作符实现："></a>14.请将以下代码修改为三元操作符实现：</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">x, y, z = <span class="number">6</span>, <span class="number">5</span>, <span class="number">4</span></span><br><span class="line"><span class="keyword">if</span> x &lt; y:</span><br><span class="line">    small = x</span><br><span class="line">    <span class="keyword">if</span> z &lt; small:</span><br><span class="line">        small = z</span><br><span class="line"><span class="keyword">elif</span> y &lt; z:</span><br><span class="line">    small = y</span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">    small = z</span><br></pre></td></tr></table></div></figure><figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">small = x <span class="keyword">if</span> (x &lt; y <span class="keyword">and</span> x &lt; z) <span class="keyword">else</span> (y <span class="keyword">if</span> y &lt; z <span class="keyword">else</span> z)</span><br></pre></td></tr></table></div></figure>        <h3 id="15-断言（assert）"   >          <a href="#15-断言（assert）" class="heading-link"><i class="fas fa-link"></i></a><a href="#15-断言（assert）" class="headerlink" title="15.断言（assert）"></a>15.断言（assert）</h3>      <p>assert这个关键字我们称之为“断言”，当这个关键字后边的条件为假时，程序自动崩溃并抛出AssertionError的异常。当这个关键字后边的条件为真时，程序无影响。</p><p>举个例子：</p><blockquote><blockquote><blockquote><p>assert 3 &gt; 4</p></blockquote></blockquote></blockquote><p>一般来说我们可以用Ta在程序中置入检查点，当需要确保程序中的某个条件一定为真才能让程序正常工作的话，assert关键字就非常有用了。</p>        <h3 id="16-下面的循环会打印多少次”I-Love-you”？"   >          <a href="#16-下面的循环会打印多少次”I-Love-you”？" class="heading-link"><i class="fas fa-link"></i></a><a href="#16-下面的循环会打印多少次”I-Love-you”？" class="headerlink" title="16. 下面的循环会打印多少次”I Love you”？"></a>16. 下面的循环会打印多少次”I Love you”？</h3>      <figure class="highlight python"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="number">10</span>, <span class="number">2</span>):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;I Love you&#x27;</span>)</span><br><span class="line"></span><br></pre></td></tr></table></div></figure><p>5 次，因为从 0 开始，到 10 结束，步进为 2。（0 2 4 6 8）</p>]]></content>
      
      
      <categories>
          
          <category> python学习 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> python </tag>
            
            <tag> 博客搭建 </tag>
            
        </tags>
      
    </entry>
    
    
    
    <entry>
      <title>记--读《西风不识相》</title>
      <link href="/2025/09/04/%E8%AE%B0%20--%E8%AF%BB%E3%80%8A%E8%A5%BF%E9%A3%8E%E4%B8%8D%E8%AF%86%E7%9B%B8%E3%80%8B/"/>
      <url>/2025/09/04/%E8%AE%B0%20--%E8%AF%BB%E3%80%8A%E8%A5%BF%E9%A3%8E%E4%B8%8D%E8%AF%86%E7%9B%B8%E3%80%8B/</url>
      
        <content type="html"><![CDATA[<p><span class="exturl"><a class="exturl__link"   href="http://www.ccview.net/htm/xiandai/wen/chenmaoping030.htm" >附上原文链接</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p><p>不太长的一篇文章，像是隔着一段时空听她在耳边慢慢讲了段故事。<br>人从来是立体复杂的。在三毛身上尤为明显。<br>她像吉普寨的长裙，没有被世俗死板的裁剪，自由而热烈，又漂泊着。<br>正是这样一个年少时便孤身出国的人，后来放下一切去撒哈拉沙漠生活的人，曾经也被一句吃亏是福裹挟着，过了半年失去自我的生活。<br>那半年里她没有原则的对人好，按照她自己的话来说，是懦弱。<br>她过的越来越没有自我，后来越来越多人无止境的索求让她疲惫。<br>所以她不是一开始就很强大，她也会做错，会痛苦，会迷惘。<br>让她吃了半年亏的从不止是父母留下的叮嘱，我想还有两点。<br>一是她内心的理想主义。她不理解别人接受了她的礼教，而没有回报以尊重。她不理解为什么她投以善意的世界 要欺压她。而在现实让她认清这些前，显然她是有误解的。</p><p>再则是她的敏感。你不能说三毛这样一个人没有自我，如果你了解她，你一定会惊叹她对自我的追随。那是什么让她在那段时间俨然是讨好型人格？——且是从内心上想让自己成为一个人缘很好的人 多办别人托的事，不拒绝别人。</p><p>是她的敏感，强大的共情力。她能敏锐的感觉到她人的态度，敏感于被认同的需求。她意识到自己是留学生，是少数者，她希望被认同，对外界环境的陌生也让她不安，所以用一种低姿态去融入，让自己更好的适应。</p><p>但是她的“讨好型人格”是表层的、策略性的；而她的“追求自我”是深层的、本质性的</p><p>敏感让她选择了讨好求安，同样是这份敏感，让她意识到那些看起来所谓的小事（院长的冤枉，她人的索求）其实是她人格，尊严，独立，的逐渐丧失。对自我的追求是她的底线，所以她掀桌子了。</p><p>她终于身临其境的面临当初没有问出口的问题–“退一步如果是深渊，也要退吗”。她用五个字给出了自己的答案—西风不识相。五个字，是批判，是不屑，也是洒脱，是自信。</p><p>一个理想主义者在面对理想与现实巨大落差时的不解和痛苦乃至愤懑，在她身上完美演绎。<br>自然，一个追随内心的人在面对抉择时的坦荡和决绝也在上演。</p><p>她的浪漫理想让她敏感的体会到了很多痛苦，而对自由和自我的追随又让她从痛苦里走出来，变的强大。</p><p>即使是世界上最自由的灵魂，也会在人情世故中笨拙地挣扎过。</p><p>不要害怕面对自己，给自己的软肋穿上盔甲。还有</p><p>“不要温驯的走进那个良夜”</p>]]></content>
      
      
      <categories>
          
          <category> 创作 </category>
          
      </categories>
      
      
        <tags>
            
            <tag> 写作 </tag>
            
            <tag> 文学 </tag>
            
        </tags>
      
    </entry>
    
    
  
  
</search>
