<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Life of Asuwill]]></title>
  <link href="http://jiangdapeng.github.io/atom.xml" rel="self"/>
  <link href="http://jiangdapeng.github.io/"/>
  <updated>2014-03-07T11:37:19+08:00</updated>
  <id>http://jiangdapeng.github.io/</id>
  <author>
    <name><![CDATA[Asuwill]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[八皇后有多少种解？]]></title>
    <link href="http://jiangdapeng.github.io/blog/2014/03/07/eight-queen-problem/"/>
    <updated>2014-03-07T10:10:00+08:00</updated>
    <id>http://jiangdapeng.github.io/blog/2014/03/07/eight-queen-problem</id>
    <content type="html"><![CDATA[<h3>什么是八皇后问题？</h3>

<blockquote><p>八皇后问题，是一个古老而著名的问题，是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出：在8X8格的国际象棋上摆放八个皇后，使其不能互相攻击，即任意两个皇后都不能处于同一行、同一列或同一斜线上，问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解，后来有人用图论的方法解出92种结果。计算机发明后，有多种方法可以解决此问题。——【百度百科】</p></blockquote>

<p>如下图所示的摆放方式就是一个满足要求的方案：
<img src="http://blog-imgs.qiniudn.com/%E5%85%AB%E7%9A%87%E5%90%8E.jpg" alt="" /></p>

<h3>八皇后有多少种解？</h3>

<p>前面引自百科的资料里也有提到，高斯认为有76种方案，还有人解出有92种方案。到底有多少种方案呢？高斯这么厉害的角色也会出错吗？我今天就想用一小段代码来求解这个问题。不过顺便说一句，人家高斯当年计算可没有计算机帮忙啊，能给出76种方案已经是非常人所能匹敌的。</p>

<h3>思路</h3>

<p>总思想：暴力破解</p>

<p>步骤一：罗列所有可能的摆放方式；</p>

<p>步骤二：检测某种摆放方式是否满足要求；</p>

<h4>步骤一</h4>

<p>方式一：罗列摆放方式，第一感觉需要一个矩阵来存储一种状态，因为棋盘是个8 * 8的方格，如果用一个8 * 8的矩阵，有皇后的用1表示，没有皇后的用0，然后再判断这个矩阵是否满足任意两个皇后没有处于同一行同一列或者同一个斜线上。这种表示方式直观，但是如果要罗列这个矩阵所有可能的状态，代价就太大了。因为每个格子都有<code>2</code>种可选状态，总共有<code>64</code>个格子，那么一共有 <code>2^64</code>个状态需要判断，明显这条路是走不通了，果断换一条路吧！</p>

<p>方式二：上面那种方式之所以不行，是因为我们没有充分利用限定条件。满足要求的摆放方式保证了每行每列都只有一个皇后，上面很多种罗列方式明显是不满足的。既然每一行都有一个皇后，那么我们用一个数组<code>column_index[8]</code>来存储每一行的皇后所在的列下标。也就是说 <code>column_index[i]</code>表示第<code>i</code>行的皇后所在的列。<code>column_index</code>如何填充呢？，只需看一下上面的图就知道，数组中必然包含<code>0~7</code>八个数字，而且每个数字必然出现一次，也就是说，一个状态就是<code>0~7</code>的一个排列。比如，上面八皇后的摆放用这种方式表示就是:</p>

<pre><code>column_index = [5, 1, 6, 0, 3, 7, 4, 2]
</code></pre>

<p>那么有多少种排列就有多少种状态需要判断，很简单，8个不同数字的排列数有<code>8！=40320</code>种，也就是说我们将需要判断的状态从 <code>2^64</code>降到了四万多。好，四万多个状态对于计算机来说判断就很快了。进入下一步吧。</p>

<h4>步骤二 判断是否合法</h4>

<p>上面的罗列方式已经确保8皇后不在同一行不在同一列，因此只需要判断是否存在两个皇后在同一个对角线，而这个只需要判断 <code>abs(i - j) == abs(column_index[i] - column_index[j])</code></p>

<p>好最后看一下代码吧</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="kn">import</span>  <span class="nn">itertools</span>
</span><span class='line'>
</span><span class='line'><span class="k">def</span> <span class="nf">is_valid_8_quene</span><span class="p">(</span><span class="n">col_index</span><span class="p">):</span>
</span><span class='line'>  <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">8</span><span class="p">):</span>
</span><span class='line'>    <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">8</span><span class="p">):</span>
</span><span class='line'>      <span class="k">if</span> <span class="n">i</span> <span class="o">!=</span> <span class="n">j</span> <span class="ow">and</span> <span class="nb">abs</span><span class="p">(</span><span class="n">i</span><span class="o">-</span><span class="n">j</span><span class="p">)</span> <span class="o">==</span> <span class="nb">abs</span><span class="p">(</span><span class="n">col_index</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">-</span> <span class="n">col_index</span><span class="p">[</span><span class="n">j</span><span class="p">])</span>
</span><span class='line'>        <span class="k">return</span> <span class="bp">False</span>
</span><span class='line'>  <span class="k">return</span> <span class="bp">True</span>
</span><span class='line'>
</span><span class='line'><span class="k">def</span> <span class="nf">count_8_quene_solutions</span><span class="p">():</span>
</span><span class='line'>  <span class="k">return</span> <span class="nb">sum</span><span class="p">([</span><span class="mi">1</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">itertools</span><span class="o">.</span><span class="n">permutations</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">8</span><span class="p">))</span> <span class="k">if</span> <span class="n">is_valid_8_quene</span><span class="p">(</span><span class="n">p</span><span class="p">)])</span>
</span><span class='line'>
</span><span class='line'><span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
</span><span class='line'>  <span class="k">print</span> <span class="p">(</span><span class="n">count_8_quene_solutions</span><span class="p">())</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<p>最后结果是多少呢？
我不会告诉你是92的</p>

<p class='post-footer'>原文地址：<a href='http://jiangdapeng.github.io/blog/2014/03/07/eight-queen-problem/'>http://jiangdapeng.github.io/blog/2014/03/07/eight-queen-problem/</a><br/>Written by <a href='http://jiangdapeng.github.io'>Asuwill</a>&nbsp;posted at <a href='http://jiangdapeng.github.io'>http://jiangdapeng.github.io</a><br/>版权声明：自由转载-非商用-非衍生-保持署名|<a href="http://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh">Creative Commons BY-NC-ND 3.0</a></p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[一分钟搞定搜索提示——freebase初体验]]></title>
    <link href="http://jiangdapeng.github.io/blog/2014/02/17/freebase-search-widget/"/>
    <updated>2014-02-17T19:58:00+08:00</updated>
    <id>http://jiangdapeng.github.io/blog/2014/02/17/freebase-search-widget</id>
    <content type="html"><![CDATA[<p>不相信？看完这篇文章，不管你信不信，反正我是信了！</p>

<p>搜索提示是什么东西，相信大家都用过google或者百度或者其他搜索引擎，当你在搜索框中敲入关键字的时候，通常会有一个搜索词推荐列表，如在google中搜索<code>freebase</code>：</p>

<p><img src="http://blog-imgs.qiniudn.com/google.JPG" alt="" /></p>

<p>这个东西真的能在一分钟内搞定？我的回答是“差不多吧”。所谓差不多吧，实际上就是还有点差距。差距在哪里就等你自己做出来慢慢去比较。下面正式开始实现了，新建一个index.html文件，内容如下：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="cp">&lt;!DOCTYPE html&gt;</span>
</span><span class='line'><span class="nt">&lt;html&gt;</span>
</span><span class='line'>    <span class="nt">&lt;head&gt;</span>
</span><span class='line'>        <span class="nt">&lt;title&gt;</span> search suggest <span class="nt">&lt;/title&gt;</span>
</span><span class='line'>        <span class="nt">&lt;link</span> <span class="na">type=</span><span class="s">&quot;text/css&quot;</span> <span class="na">rel=</span><span class="s">&quot;stylesheet&quot;</span> <span class="na">href=</span><span class="s">&quot;https://www.gstatic.com/freebase/suggest/4_2/suggest.min.css&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>        <span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/javascript&quot;</span> <span class="na">src=</span><span class="s">&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
</span><span class='line'>        <span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/javascript&quot;</span> <span class="na">src=</span><span class="s">&quot;https://www.gstatic.com/freebase/suggest/4_2/suggest.min.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
</span><span class='line'>        <span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/javascript&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>        <span class="nx">$</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>          <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#search&quot;</span><span class="p">).</span><span class="nx">suggest</span><span class="p">({</span>
</span><span class='line'>          <span class="nx">key</span><span class="o">:</span> <span class="s1">&#39;your-api-key-of-freebase&#39;</span><span class="p">,</span>
</span><span class='line'>          <span class="nx">lang</span><span class="o">:</span><span class="s1">&#39;zh&#39;</span><span class="p">});</span>
</span><span class='line'>        <span class="p">});</span>
</span><span class='line'>        <span class="nt">&lt;/script&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/head&gt;</span>
</span><span class='line'>
</span><span class='line'>    <span class="nt">&lt;body&gt;</span>
</span><span class='line'>    <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;text&quot;</span> <span class="na">id=</span><span class="s">&quot;search&quot;</span> <span class="na">placeholder=</span><span class="s">&quot;search&quot;</span><span class="nt">&gt;</span> <span class="nt">&lt;/input&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/body&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="nt">&lt;/html&gt;</span>
</span><span class='line'>
</span></code></pre></td></tr></table></div></figure>


<p>好了，一切准备就绪了，请用你最喜爱的浏览器打开这个文件，在出现的搜索框里输入一些关键字试试，就比如<code>freebase</code>吧，如果你还不知道这是个什么。现在你相信了我说的没有？</p>

<p>当然，这都是用的别人的现成的东西构建的，算不上什么真本事。但是，你也可能听到过另外一句话，&#8221;不要重复造轮子”，有些时候就应该采用拿来主义，把他人的东西纳为己用，这是对别人成果的肯定！所以我今天想在这里推荐的就是别人做好的东西，做的好东西，那就是——<strong>freebase</strong>。刚才所做的只是一个基于<code>freebase</code>的<code>jquery插件</code>，叫做<a href="https://developers.google.com/freebase/v1/search-widget"><code>freebase search widget</code></a>。</p>

<p><code>freebase</code>是<code>google knowledge graph</code>的基础，通俗来说，它是一堆事实的网络集合。它‘知道’<code>神偷奶爸</code>是一部动画电影，哪个公司发行的，哪年上映的，还知道这部电影的另外一个名字叫做<code>卑鄙的我</code>。在这里，存储的不再只是纯粹的字符串，这些字符串代表了某个本体，具有一定的属性。更详细的介绍可以参见freebase<a href="http://www.freebase.com/">官网</a>。</p>

<p>今天这个作为一个探索freebase的开始，后续我将继续深入了解freebase及其它所代表的新一代基于知识的搜索引擎。<p class='post-footer'>原文地址：<a href='http://jiangdapeng.github.io/blog/2014/02/17/freebase-search-widget/'><a href="http://jiangdapeng.github.io/blog/2014/02/17/freebase-search-widget/">http://jiangdapeng.github.io/blog/2014/02/17/freebase-search-widget/</a></a><br/>Written by <a href='http://jiangdapeng.github.io'>Asuwill</a>&nbsp;posted at <a href='http://jiangdapeng.github.io'><a href="http://jiangdapeng.github.io">http://jiangdapeng.github.io</a></a><br/>版权声明：自由转载-非商用-非衍生-保持署名|<a href="http://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh">Creative Commons BY-NC-ND 3.0</a></p></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[说一说python中的yield]]></title>
    <link href="http://jiangdapeng.github.io/blog/2014/02/16/python-yield/"/>
    <updated>2014-02-16T21:41:00+08:00</updated>
    <id>http://jiangdapeng.github.io/blog/2014/02/16/python-yield</id>
    <content type="html"><![CDATA[<h2>yield是什么？</h2>

<h2>yield能做什么？</h2>

<h2>如何用yield</h2>

<h2>参考文献</h2>

<ol>
<li><p>提高你的Python: 解释‘yield’和‘Generators（生成器）
<a href="http://www.oschina.net/translate/improve-your-python-yield-and-generators-explained">http://www.oschina.net/translate/improve-your-python-yield-and-generators-explained</a></p></li>
<li><p>python yield浅析
<a href="https://www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/">https://www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/</a></p></li>
<li><p>python关键字yield的解释
<a href="https://pyzh.readthedocs.org/en/latest/the-python-yield-keyword-explained.html">https://pyzh.readthedocs.org/en/latest/the-python-yield-keyword-explained.html</a></p></li>
</ol>


<p class='post-footer'>原文地址：<a href='http://jiangdapeng.github.io/blog/2014/02/16/python-yield/'>http://jiangdapeng.github.io/blog/2014/02/16/python-yield/</a><br/>Written by <a href='http://jiangdapeng.github.io'>Asuwill</a>&nbsp;posted at <a href='http://jiangdapeng.github.io'>http://jiangdapeng.github.io</a><br/>版权声明：自由转载-非商用-非衍生-保持署名|<a href="http://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh">Creative Commons BY-NC-ND 3.0</a></p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[基础数据结构与算法——排序]]></title>
    <link href="http://jiangdapeng.github.io/blog/2013/10/27/basic-data-structures-and-algorithms-1/"/>
    <updated>2013-10-27T22:39:00+08:00</updated>
    <id>http://jiangdapeng.github.io/blog/2013/10/27/basic-data-structures-and-algorithms-1</id>
    <content type="html"><![CDATA[<p>最近几天在重温基础的数据结构和算法，比如基础的排序算法，以及动态规划的应用，也慢慢的在博客上写一个基础的系列吧，作为自己温习的记录。</p>

<h2>排序算法</h2>

<h3>插入排序</h3>

<p>虽然插入排序的时间复杂度期望是O（n<sup>2</sup>)，但是具有实现简单，属于<strong><em>原地排序</em></strong>，并且是<strong><em>稳定排序</em></strong>的特点。之所以将其叫做插入排序，是因为，每一轮操作都是将一个<strong><em>待排序</em></strong>的数插入到一个<strong><em>已经排好序</em></strong>的序列中，过程可以想象将一张扑克牌插入到已经按顺序摆好的扑克牌中，代码如下：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="kt">void</span> <span class="n">insertion_sort</span><span class="p">(</span><span class="kt">int</span> <span class="n">A</span><span class="p">[],</span> <span class="kt">int</span> <span class="n">low</span> <span class="p">,</span> <span class="kt">int</span> <span class="n">high</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="n">low</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">high</span><span class="p">;</span><span class="o">++</span><span class="n">i</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="kt">int</span> <span class="n">x</span> <span class="o">=</span> <span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>  <span class="c1">// 当前需要排序的数，它之前的数都已经排好序了</span>
</span><span class='line'>      <span class="kt">int</span> <span class="n">j</span> <span class="o">=</span> <span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>      <span class="k">while</span><span class="p">(</span><span class="n">j</span> <span class="o">&gt;=</span><span class="n">low</span> <span class="o">&amp;&amp;</span> <span class="n">A</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">x</span><span class="p">)</span>
</span><span class='line'>      <span class="p">{</span>
</span><span class='line'>          <span class="n">A</span><span class="p">[</span><span class="n">j</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">A</span><span class="p">[</span><span class="n">j</span><span class="p">];</span>
</span><span class='line'>          <span class="n">j</span><span class="o">--</span><span class="p">;</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>      <span class="n">A</span><span class="p">[</span><span class="n">j</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">x</span><span class="p">;</span>  <span class="c1">// 将 x 放置在正确的位置</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<!--more-->


<h3>堆排序</h3>

<p>这里的堆排序，特指利用二叉堆进行排序操作，在讲排序前，得先把堆的构建、取最大（最小值）等操作进行介绍。二叉堆实际上是在数组上实现的一个树形结构，而窍门就在于，通过将根元素放置在下标为<strong><em><code>1</code></em></strong>的位置，元素的父节点和左右孩子节点的位置都可以通过简单的运算得到。</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="c1">// 节点 i 的父节点下标 i/2</span>
</span><span class='line'><span class="kr">inline</span> <span class="kt">int</span> <span class="n">PARENT</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="n">i</span> <span class="o">&gt;&gt;</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// 左孩子 2*i</span>
</span><span class='line'><span class="kr">inline</span> <span class="kt">int</span> <span class="n">LEFT</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="n">i</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// 右孩子 2*i + 1</span>
</span><span class='line'><span class="kr">inline</span> <span class="kt">int</span> <span class="n">RIGHT</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="p">(</span><span class="n">i</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kr">inline</span> <span class="kt">void</span> <span class="n">SWAP</span><span class="p">(</span><span class="kt">int</span><span class="o">&amp;</span> <span class="n">a</span><span class="p">,</span> <span class="kt">int</span><span class="o">&amp;</span> <span class="n">b</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">t</span> <span class="o">=</span> <span class="n">a</span><span class="p">;</span>
</span><span class='line'>  <span class="n">a</span> <span class="o">=</span> <span class="n">b</span><span class="p">;</span>
</span><span class='line'>  <span class="n">b</span> <span class="o">=</span> <span class="n">t</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// 这个纯粹了方便查看一个堆的情况</span>
</span><span class='line'><span class="kt">void</span> <span class="n">print_heap</span><span class="p">(</span><span class="kt">int</span> <span class="n">A</span><span class="p">[],</span><span class="kt">int</span> <span class="n">n</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
</span><span class='line'>  <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">2</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;=</span><span class="n">n</span><span class="p">;</span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span><span class='line'>      <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&quot; &quot;</span> <span class="o">&lt;&lt;</span> <span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
</span><span class='line'>  <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">endl</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// 大顶堆，使得以A[i]为根的子树 是个合法的大顶堆</span>
</span><span class='line'><span class="kt">void</span> <span class="n">max_heapify</span><span class="p">(</span><span class="kt">int</span> <span class="n">A</span><span class="p">[],</span><span class="kt">int</span> <span class="n">i</span><span class="p">,</span><span class="kt">int</span> <span class="n">n</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">left</span> <span class="o">=</span> <span class="n">LEFT</span><span class="p">(</span><span class="n">i</span><span class="p">);</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">right</span> <span class="o">=</span> <span class="n">RIGHT</span><span class="p">(</span><span class="n">i</span><span class="p">);</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">next</span> <span class="o">=</span> <span class="n">i</span><span class="p">;</span>
</span><span class='line'>  <span class="c1">// 选出左右孩子中最大的元素</span>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span><span class="n">left</span> <span class="o">&lt;=</span><span class="n">n</span> <span class="o">&amp;&amp;</span> <span class="n">A</span><span class="p">[</span><span class="n">left</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">A</span><span class="p">[</span><span class="n">next</span><span class="p">])</span> <span class="n">next</span> <span class="o">=</span> <span class="n">left</span><span class="p">;</span>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span><span class="n">right</span> <span class="o">&lt;=</span><span class="n">n</span> <span class="o">&amp;&amp;</span> <span class="n">A</span><span class="p">[</span><span class="n">right</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">A</span><span class="p">[</span><span class="n">next</span><span class="p">])</span> <span class="n">next</span> <span class="o">=</span> <span class="n">right</span><span class="p">;</span>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span><span class="n">next</span> <span class="o">!=</span> <span class="n">i</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="n">SWAP</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="n">next</span><span class="p">],</span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
</span><span class='line'>      <span class="n">max_heapify</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">next</span><span class="p">,</span><span class="n">n</span><span class="p">);</span> <span class="c1">// 递归的往下操作</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="n">build_heap</span><span class="p">(</span><span class="kt">int</span> <span class="n">A</span><span class="p">[],</span> <span class="kt">int</span> <span class="n">n</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="c1">// A[i+1],A[i+2],...,A[n]都是叶子节点，只需要从非叶子节点开始</span>
</span><span class='line'>  <span class="c1">// 这个操作严格的时间复杂度是O(n)</span>
</span><span class='line'>  <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="n">n</span><span class="o">/</span><span class="mi">2</span><span class="p">;</span><span class="n">i</span><span class="o">&gt;</span><span class="mi">0</span><span class="p">;</span><span class="o">--</span><span class="n">i</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="n">max_heapify</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">i</span><span class="p">,</span><span class="n">n</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="n">heap_sort</span><span class="p">(</span><span class="kt">int</span> <span class="n">A</span><span class="p">[],</span> <span class="kt">int</span> <span class="n">n</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="c1">// 注意 A 中的有效元素应该从下标为1开始</span>
</span><span class='line'>  <span class="c1">// 整个的复杂度是O(N*logN)</span>
</span><span class='line'>  <span class="n">build_heap</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">n</span><span class="p">);</span> <span class="c1">// 建立最大堆, O(n)</span>
</span><span class='line'>  <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="n">n</span><span class="p">;</span><span class="n">i</span><span class="o">&gt;</span><span class="mi">1</span><span class="p">;</span><span class="o">--</span><span class="n">i</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="n">SWAP</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
</span><span class='line'>      <span class="n">max_heapify</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="c1">// O(logN)</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h3>快速排序</h3>

<p>快速排序的核心思想是分治，如何分就成了关键问题。快速排序的想法是:</p>

<blockquote><p>先找到序列中的某个数<code>x</code>，然后将所有小于或等于<code>x</code>的数都放到<code>x</code>前面，大于<code>x</code>的数都放在它后面，然后再分别对前后两个部分进行排序。这个过程被称为<code>选主元</code>。选的过程也将数据进行了一次划分。</p></blockquote>

<p>主元的选择的好坏对算法的性能有影响，原因就在于，如果主元的值合适的话，前后两个子问题的规模可以迅速地降低。例如，如果每次主元都恰好是中间值，那么子问题的规模就以指数形式降低，<code>n/2,  n/4, ..., n/2^k</code>。一种常见的选择主元的方式如下：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="c1">// 选择最后一个数做主元</span>
</span><span class='line'><span class="kt">int</span> <span class="n">partition</span><span class="p">(</span><span class="kt">int</span> <span class="n">A</span><span class="p">[],</span> <span class="kt">int</span> <span class="n">low</span><span class="p">,</span> <span class="kt">int</span> <span class="n">high</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">x</span> <span class="o">=</span> <span class="n">A</span><span class="p">[</span><span class="n">high</span><span class="p">];</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">low</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>  <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">j</span> <span class="o">=</span> <span class="n">low</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">high</span><span class="p">;</span><span class="o">++</span><span class="n">j</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="c1">// 找到所有小于或等于 x的数，交换到前面</span>
</span><span class='line'>      <span class="k">if</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">&lt;=</span> <span class="n">x</span><span class="p">)</span>
</span><span class='line'>      <span class="p">{</span>
</span><span class='line'>          <span class="n">i</span><span class="o">++</span><span class="p">;</span>
</span><span class='line'>          <span class="n">SWAP</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">],</span><span class="n">A</span><span class="p">[</span><span class="n">j</span><span class="p">]);</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="n">SWAP</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">],</span><span class="n">A</span><span class="p">[</span><span class="n">high</span><span class="p">]);</span> <span class="c1">// after this , A[i+1] = x</span>
</span><span class='line'>  <span class="k">return</span> <span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="n">quick_sort</span><span class="p">(</span><span class="kt">int</span> <span class="n">A</span><span class="p">[],</span> <span class="kt">int</span> <span class="n">low</span> <span class="p">,</span><span class="kt">int</span> <span class="n">high</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span><span class="n">low</span> <span class="o">&lt;</span> <span class="n">high</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="kt">int</span> <span class="n">p</span> <span class="o">=</span> <span class="n">partition</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">low</span><span class="p">,</span><span class="n">high</span><span class="p">);</span>
</span><span class='line'>      <span class="n">quick_sort</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">low</span><span class="p">,</span><span class="n">p</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span>       <span class="c1">// 对前半部分排序</span>
</span><span class='line'>      <span class="n">quick_sort</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">p</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span><span class="n">high</span><span class="p">);</span>      <span class="c1">// 对后半部分排序</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>如果数据的顺序是随机的，那么这种方式的平均性能并没有什么问题。但是对某些特定顺序的数据，这种方式的快速排序，性能会处于最坏情况，也就是说，时间复杂度是<code>O（n^2)</code>。比如说，数组已经排好序了，那么每次划分后的子问题规模是线性减小的（由<code>n -&gt; n-1 -&gt; n-2  -&gt; ... -&gt; 1</code>），最终整体的复杂度也就是<code>O(n^2)</code>。为了避免这种问题，有一个稍微改进的选主元的方式：</p>

<blockquote><p>每次先选择序列中的三个数，然后选择这三个数的中间那个数作为主元。或者是采用随机函数，随机选择某个数作为主元</p></blockquote>

<p>这种方式几乎可以避免非常坏的情况出现，除非是针对算法特意构造出来的序列。下面给出三选一的一种实现：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="c1">// 选择三个数的中间数作为主元</span>
</span><span class='line'><span class="kt">int</span> <span class="n">median_partition</span><span class="p">(</span><span class="kt">int</span> <span class="n">A</span><span class="p">[],</span> <span class="kt">int</span> <span class="n">low</span><span class="p">,</span> <span class="kt">int</span> <span class="n">high</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">a</span> <span class="o">=</span> <span class="n">A</span><span class="p">[</span><span class="n">low</span><span class="p">];</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">b</span> <span class="o">=</span> <span class="n">A</span><span class="p">[</span><span class="n">high</span><span class="p">];</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">c</span> <span class="o">=</span> <span class="n">A</span><span class="p">[(</span><span class="n">low</span><span class="o">+</span><span class="n">high</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="p">];</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">x</span> <span class="o">=</span> <span class="p">(</span><span class="n">a</span> <span class="o">&lt;=</span><span class="n">b</span> <span class="o">&amp;&amp;</span> <span class="n">b</span><span class="o">&lt;=</span> <span class="n">c</span> <span class="o">||</span> <span class="n">a</span> <span class="o">&gt;=</span> <span class="n">b</span> <span class="o">&amp;&amp;</span> <span class="n">b</span> <span class="o">&gt;=</span> <span class="n">c</span><span class="p">)</span><span class="o">?</span><span class="nl">b:</span><span class="p">(</span><span class="n">b</span><span class="o">&lt;=</span> <span class="n">a</span> <span class="o">&amp;&amp;</span> <span class="n">a</span> <span class="o">&lt;=</span> <span class="n">c</span> <span class="o">||</span> <span class="n">c</span> <span class="o">&lt;=</span> <span class="n">a</span> <span class="o">&amp;&amp;</span> <span class="n">a</span> <span class="o">&lt;=</span> <span class="n">b</span><span class="p">)</span><span class="o">?</span><span class="nl">a:</span><span class="n">c</span><span class="p">;</span>
</span><span class='line'>  <span class="c1">// 后面的代码都跟前一种实现相同</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">low</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>  <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">j</span> <span class="o">=</span> <span class="n">low</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">high</span><span class="p">;</span><span class="o">++</span><span class="n">j</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="k">if</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">&lt;=</span> <span class="n">x</span><span class="p">)</span>
</span><span class='line'>      <span class="p">{</span>
</span><span class='line'>          <span class="n">i</span><span class="o">++</span><span class="p">;</span>
</span><span class='line'>          <span class="n">SWAP</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">],</span><span class="n">A</span><span class="p">[</span><span class="n">j</span><span class="p">]);</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="n">SWAP</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">],</span><span class="n">A</span><span class="p">[</span><span class="n">high</span><span class="p">]);</span> <span class="c1">// after this , A[i+1] = x</span>
</span><span class='line'>  <span class="k">return</span> <span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h3>归并排序&amp;others</h3>

<p>归并排序核心思想也是<code>分治</code>，它与快排不同的地方在与，你可以选择以最优的方式来划分子问题（在二归并中，你可以每次都从<code>n/2</code>处划分），因此归并排序在最坏情况下时间复杂度也是<code>O(n*logn)</code>。但是它也有较明显的不足之处：归并排序不是<code>原地排序</code>，主要是在合并的过程中需要利用<code>O(n)</code>的额外空间。以下是归并排序的伪代码：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="kt">void</span> <span class="n">merge_sort</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="n">low</span><span class="p">,</span> <span class="n">high</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span><span class="n">low</span> <span class="o">&lt;</span> <span class="n">high</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="n">middle</span> <span class="o">=</span> <span class="p">(</span><span class="n">low</span> <span class="o">+</span> <span class="n">high</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="p">;</span>
</span><span class='line'>      <span class="n">merge_sort</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">low</span><span class="p">,</span><span class="n">middle</span><span class="p">);</span>
</span><span class='line'>      <span class="n">merge_sort</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">middle</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span><span class="n">high</span><span class="p">);</span>
</span><span class='line'>      <span class="n">merge</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">low</span><span class="p">,</span><span class="n">middle</span><span class="p">,</span><span class="n">high</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>递归的代码写起来确实非常简洁，但是注意到中间调用了一个<code>merge</code>函数，这个函数并不是递归的，<code>merge</code>的思路也很简单，因为需要合并的两个序列都是已经排好序的，那么每次取两个序列头部的小者填入正确的位置即可。伪代码如下：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="kt">void</span> <span class="n">merge</span><span class="p">(</span><span class="n">A</span><span class="p">,</span><span class="n">low</span><span class="p">,</span><span class="n">middle</span><span class="p">,</span><span class="n">high</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="n">n1</span> <span class="o">=</span> <span class="n">middle</span> <span class="o">-</span> <span class="n">low</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">// 前一部分元素的个数</span>
</span><span class='line'>  <span class="n">n2</span> <span class="o">=</span> <span class="n">high</span> <span class="o">-</span> <span class="n">middle</span><span class="p">;</span>      <span class="c1">// 后一部分元素的个数</span>
</span><span class='line'>  <span class="err">创建数组</span> <span class="n">left</span><span class="p">[</span><span class="n">n1</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> <span class="err">以及</span> <span class="n">right</span><span class="p">[</span><span class="n">n2</span><span class="o">+</span><span class="mi">1</span><span class="p">];</span>
</span><span class='line'>  <span class="k">for</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span> <span class="n">to</span> <span class="n">n1</span> <span class="o">-</span> <span class="mi">1</span>
</span><span class='line'>      <span class="n">left</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">A</span><span class="p">[</span><span class="n">low</span><span class="o">+</span><span class="n">i</span><span class="p">];</span>
</span><span class='line'>  <span class="k">for</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span> <span class="n">to</span> <span class="n">n2</span> <span class="o">-</span> <span class="mi">1</span>
</span><span class='line'>      <span class="n">right</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">A</span><span class="p">[</span><span class="n">middle</span> <span class="o">+</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">i</span><span class="p">];</span>
</span><span class='line'>  <span class="n">left</span><span class="p">[</span><span class="n">n1</span><span class="p">]</span> <span class="o">=</span> <span class="n">INT_MAX</span><span class="p">;</span>        <span class="c1">// 作为哨兵</span>
</span><span class='line'>  <span class="n">right</span><span class="p">[</span><span class="n">n2</span><span class="p">]</span> <span class="o">=</span> <span class="n">INT_MAX</span><span class="p">;</span>   
</span><span class='line'>  <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'>  <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'>  <span class="k">for</span> <span class="n">k</span> <span class="o">=</span> <span class="n">low</span> <span class="n">to</span> <span class="n">high</span>
</span><span class='line'>      <span class="k">if</span><span class="p">(</span><span class="n">left</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&lt;=</span> <span class="n">right</span><span class="p">[</span><span class="n">j</span><span class="p">])</span>
</span><span class='line'>          <span class="n">A</span><span class="p">[</span><span class="n">k</span><span class="p">]</span> <span class="o">=</span> <span class="n">left</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
</span><span class='line'>          <span class="n">i</span><span class="o">++</span><span class="p">;</span>
</span><span class='line'>      <span class="k">else</span>
</span><span class='line'>          <span class="n">A</span><span class="p">[</span><span class="n">k</span><span class="p">]</span> <span class="o">=</span> <span class="n">right</span><span class="p">[</span><span class="n">j</span><span class="p">];</span>
</span><span class='line'>          <span class="n">j</span><span class="o">++</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>归并的思想还是非常不错的。特别是在需要排序的数非常之多，以至于都无法一次载入内存的时候，就可以利用归并的思想，先将数据分块，将每一块都排序后再逐个合并在一起。</p>

<p>另外还有其他的排序算法，如冒泡排序，好像大学学到的第一个排序算法就是这个？希尔排序，对插入排序的改进，以及<code>不是基于比较的排序算法</code>，如<code>count sort</code>、<code>radix sort</code>、<code>bucket sort</code>等等，后面几种下一次再说。</p>

<p class='post-footer'>原文地址：<a href='http://jiangdapeng.github.io/blog/2013/10/27/basic-data-structures-and-algorithms-1/'>http://jiangdapeng.github.io/blog/2013/10/27/basic-data-structures-and-algorithms-1/</a><br/>Written by <a href='http://jiangdapeng.github.io'>Asuwill</a>&nbsp;posted at <a href='http://jiangdapeng.github.io'>http://jiangdapeng.github.io</a><br/>版权声明：自由转载-非商用-非衍生-保持署名|<a href="http://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh">Creative Commons BY-NC-ND 3.0</a></p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[PAT-1011-1015-题解]]></title>
    <link href="http://jiangdapeng.github.io/blog/2013/10/22/pat-1011-1015-solutions/"/>
    <updated>2013-10-22T21:08:00+08:00</updated>
    <id>http://jiangdapeng.github.io/blog/2013/10/22/pat-1011-1015-solutions</id>
    <content type="html"><![CDATA[<h2><a href="http://pat.zju.edu.cn/contests/pat-a-practise/1011" title="1011">1011. World Cup Betting (20)</a></h2>

<h3>题意</h3>

<p>赌博，怎么猜硬的最多</p>

<h3>思路</h3>

<p>简单题，选出每个比赛投注投哪个盈利最大即可</p>

<p class='post-footer'>原文地址：<a href='http://jiangdapeng.github.io/blog/2013/10/22/pat-1011-1015-solutions/'>http://jiangdapeng.github.io/blog/2013/10/22/pat-1011-1015-solutions/</a><br/>Written by <a href='http://jiangdapeng.github.io'>Asuwill</a>&nbsp;posted at <a href='http://jiangdapeng.github.io'>http://jiangdapeng.github.io</a><br/>版权声明：自由转载-非商用-非衍生-保持署名|<a href="http://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh">Creative Commons BY-NC-ND 3.0</a></p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[PAT 1001-1010 题解]]></title>
    <link href="http://jiangdapeng.github.io/blog/2013/10/20/pat-1001-1010-solutions/"/>
    <updated>2013-10-20T09:45:00+08:00</updated>
    <id>http://jiangdapeng.github.io/blog/2013/10/20/pat-1001-1010-solutions</id>
    <content type="html"><![CDATA[<h2>前言</h2>

<p>PAT 是浙江大学搞出来的一个编程（<strong>P</strong>rogramming）能力（<strong>A</strong>bility）测试（<strong>T</strong>est），在姥姥的大力推广下，目前也逐渐走上了正道，详细介绍可以直接到官网查看 <a href="http://pat.zju.edu.cn/" title="PAT官方网站">http://pat.zju.edu.cn/</a></p>

<p>我断断续续也将上面的题目做得差不多了，想来也应该总结一下，算是给自己一个交代。题解大致的形式将会是每10个（或者少于10个）题目一篇博文，对每个题目而言，会简述题目大意，然后是思路整理，然后是代码链接。我已经完成的题目的代码都在github上，<a href="https://github.com/jiangdapeng/pat" title="pat 源代码">请戳我</a></p>

<h2><a href="http://pat.zju.edu.cn/contests/pat-a-practise/1001" title="1001. A+B Format (20)">1001. A+B Format (20)</a></h2>

<h3>题意</h3>

<p>按照给定的格式输出两个整数的和：即每三位数一组用逗号分隔，例如 <code>999991</code> 就应该输出为 <code>999,991</code></p>

<h3>思路</h3>

<p>简单题，可以将和每次三位取出（即按照<code>1000进制</code>），然后再从高位开始输出即可，注意处理负数，中间合适的位置加上<code>,</code>
主要代码如下：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="kt">void</span> <span class="n">format</span><span class="p">(</span><span class="kt">int</span>  <span class="n">n</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="kt">bool</span> <span class="n">neg</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span><span class="n">n</span><span class="o">&lt;</span><span class="mi">0</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>    <span class="n">neg</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
</span><span class='line'>    <span class="n">n</span> <span class="o">=</span> <span class="o">-</span><span class="n">n</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="n">stack</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">vi</span><span class="p">;</span>
</span><span class='line'>  <span class="k">do</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>    <span class="n">vi</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">n</span><span class="o">%</span><span class="mi">1000</span><span class="p">);</span>
</span><span class='line'>    <span class="n">n</span> <span class="o">/=</span> <span class="mi">1000</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span><span class="k">while</span><span class="p">(</span><span class="n">n</span><span class="o">!=</span><span class="mi">0</span><span class="p">);</span>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span><span class="n">neg</span><span class="p">)</span>
</span><span class='line'>    <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&quot;-&quot;</span><span class="p">;</span>
</span><span class='line'>  <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">vi</span><span class="p">.</span><span class="n">top</span><span class="p">();</span>
</span><span class='line'>  <span class="n">vi</span><span class="p">.</span><span class="n">pop</span><span class="p">();</span>
</span><span class='line'>  <span class="k">while</span><span class="p">(</span><span class="o">!</span><span class="n">vi</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">top</span> <span class="o">=</span> <span class="n">vi</span><span class="p">.</span><span class="n">top</span><span class="p">();</span>
</span><span class='line'>    <span class="n">vi</span><span class="p">.</span><span class="n">pop</span><span class="p">();</span>
</span><span class='line'>    <span class="n">printf</span><span class="p">(</span><span class="s">&quot;,%03d&quot;</span><span class="p">,</span><span class="n">top</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">endl</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>
完整代码<a href="https://github.com/jiangdapeng/pat/blob/master/Advanced%20Level/1001.%20A%2BB%20Format%20(20).cpp" title="1001">请戳我</a></p>

<!--more-->


<h2><a href="http://pat.zju.edu.cn/contests/pat-a-practise/1002" title="1002. A+B for Polynomials (25)">1002. A+B for Polynomials (25)</a></h2>

<h3>题意</h3>

<p>求两个多项式的和，<code>a</code> 和 <code>b</code> 都以 <code>K N1 aN1 N2 aN2 ... NK aNK</code>的形式表示，其中 <code>K</code> 表示多项式中中非零项的个数，<code>Ni</code> 和 <code>aNi</code> 分别表示指数和系数</p>

<h3>思路</h3>

<p>类似于归并的思想，从高到低将指数相同的项的系数加起来，如果某指数项只在一个数中有，直接保留在结果里即可，需要注意的是如果系数加起来为0，这一项就不能放进结果。
核心代码：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'>  <span class="c1">// p1+p1</span>
</span><span class='line'>  <span class="n">vector</span><span class="o">&lt;</span><span class="n">Poly</span><span class="o">&gt;</span> <span class="n">result</span><span class="p">;</span>
</span><span class='line'>  <span class="n">vector</span><span class="o">&lt;</span><span class="n">Poly</span><span class="o">&gt;::</span><span class="n">iterator</span> <span class="n">vi1</span> <span class="o">=</span> <span class="n">p1</span><span class="p">.</span><span class="n">begin</span><span class="p">();</span>
</span><span class='line'>  <span class="n">vector</span><span class="o">&lt;</span><span class="n">Poly</span><span class="o">&gt;::</span><span class="n">iterator</span> <span class="n">vi2</span> <span class="o">=</span> <span class="n">p2</span><span class="p">.</span><span class="n">begin</span><span class="p">();</span>
</span><span class='line'>  <span class="k">while</span><span class="p">((</span><span class="n">vi1</span> <span class="o">!=</span> <span class="n">p1</span><span class="p">.</span><span class="n">end</span><span class="p">())</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="n">vi2</span><span class="o">!=</span> <span class="n">p2</span><span class="p">.</span><span class="n">end</span><span class="p">()))</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="n">vi1</span><span class="o">-&gt;</span><span class="n">exp</span> <span class="o">==</span> <span class="n">vi2</span><span class="o">-&gt;</span><span class="n">exp</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>      <span class="n">tmp</span><span class="p">.</span><span class="n">exp</span> <span class="o">=</span> <span class="n">vi1</span><span class="o">-&gt;</span><span class="n">exp</span><span class="p">;</span>
</span><span class='line'>      <span class="n">tmp</span><span class="p">.</span><span class="n">coe</span> <span class="o">=</span> <span class="n">vi1</span><span class="o">-&gt;</span><span class="n">coe</span> <span class="o">+</span> <span class="n">vi2</span><span class="o">-&gt;</span><span class="n">coe</span><span class="p">;</span>
</span><span class='line'>      <span class="k">if</span><span class="p">(</span><span class="n">tmp</span><span class="p">.</span><span class="n">coe</span> <span class="o">!=</span><span class="mi">0</span><span class="p">)</span>
</span><span class='line'>        <span class="n">result</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">tmp</span><span class="p">);</span>
</span><span class='line'>      <span class="o">++</span><span class="n">vi1</span><span class="p">;</span>
</span><span class='line'>      <span class="o">++</span><span class="n">vi2</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">vi1</span><span class="o">-&gt;</span><span class="n">exp</span> <span class="o">&gt;</span> <span class="n">vi2</span><span class="o">-&gt;</span><span class="n">exp</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>      <span class="n">result</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="o">*</span><span class="n">vi1</span><span class="p">);</span>
</span><span class='line'>      <span class="o">++</span><span class="n">vi1</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">else</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>      <span class="n">result</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="o">*</span><span class="n">vi2</span><span class="p">);</span>
</span><span class='line'>      <span class="o">++</span><span class="n">vi2</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="k">while</span><span class="p">(</span><span class="n">vi1</span> <span class="o">!=</span> <span class="n">p1</span><span class="p">.</span><span class="n">end</span><span class="p">())</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>    <span class="n">result</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="o">*</span><span class="n">vi1</span><span class="p">);</span>
</span><span class='line'>    <span class="o">++</span><span class="n">vi1</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="k">while</span><span class="p">(</span><span class="n">vi2</span> <span class="o">!=</span> <span class="n">p2</span><span class="p">.</span><span class="n">end</span><span class="p">())</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>    <span class="n">result</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="o">*</span><span class="n">vi2</span><span class="p">);</span>
</span><span class='line'>    <span class="o">++</span><span class="n">vi2</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>完整代码<a href="https://github.com/jiangdapeng/pat/blob/master/Advanced%20Level/1002.%20A%2BB%20for%20Polynomials%20(25).cpp" title="1002">请戳我</a></p>

<h2><a href="http://pat.zju.edu.cn/contests/pat-a-practise/1003" title="pat 1003">1003. Emergency (25)</a></h2>

<h3>题意</h3>

<p>给定城市之间的道路距离，以及每个城市的营救队的人数，求从城市 <code>c1</code> 到 <code>c2</code>的最短路径的条数，以及沿途能够召集的最大人数。</p>

<h3>思路</h3>

<p>典型的最短路径题，采用Dijkstra算法，但是这里不仅仅是找出一条最短路径，而是要计算最短路径的条数，并且需要统计沿途能够召集的最大人数。能够召集的人数没什么问题，只需要在最短路径的基础上加上一个人数的比较，<code>callup[c]</code>表示达到<code>城市c</code>的时候能够召集的最大人数。用<code>count_path[c]</code>表示到达<code>城市c</code>的最短路径的条数。</p>

<ol>
<li>如果 <code>dist[c] + edge[c,adj] &lt; dist[adj]</code> 则  <code>dist[adj] = dist[c] + edge[c,adj]; count_path[adj] = count_path[c]； callup[adj] = callup[c] + people[adj]</code></li>
<li>如果 <code>dist[c] + edge[c,adj] == dist[adj]</code> 也就是有多条距离相同的路径到达城市<code>adj</code>，这个时候 <code>count_path[adj] = count_path[adj] + count_path[c]; callup[adj] = max { callup[adj], callup[c] + people[adj] }</code></li>
</ol>


<p>代码结构：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'>  <span class="c1">// start from start city</span>
</span><span class='line'>  <span class="n">dist</span><span class="p">[</span><span class="n">start</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'>  <span class="n">count</span><span class="p">[</span><span class="n">start</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span><span class="c1">// one shortest path from start to start</span>
</span><span class='line'>  <span class="n">callup</span><span class="p">[</span><span class="n">start</span><span class="p">]</span> <span class="o">=</span> <span class="n">people</span><span class="p">[</span><span class="n">start</span><span class="p">];</span>
</span><span class='line'>  <span class="k">while</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">city</span> <span class="o">=</span> <span class="n">nearest_city</span><span class="p">();</span>
</span><span class='line'>    <span class="n">visited</span><span class="p">[</span><span class="n">city</span><span class="p">]</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
</span><span class='line'>    <span class="k">if</span><span class="p">(</span><span class="n">city</span> <span class="o">==</span> <span class="n">end</span><span class="p">)</span>
</span><span class='line'>      <span class="k">break</span><span class="p">;</span>
</span><span class='line'>    <span class="n">update_neighbor</span><span class="p">(</span><span class="n">city</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p><code>nearest_city</code>，可以通过<code>priority_queue</code>最小堆实现，我当时用了线性遍历查找，因为测试数据小，也能过。</p>

<p>完整代码<a href="https://github.com/jiangdapeng/pat/blob/master/Advanced%20Level/1003.%20Emergency%20(25).cpp" title="1003">请戳我</a></p>

<h2><a href="http://pat.zju.edu.cn/contests/pat-a-practise/1004" title="1004">1004. Counting Leaves (30)</a></h2>

<h3>题意</h3>

<p>统计一个家谱树中没有孩子的成员，也就是叶子节点的个数，题目要求按层输出每一层没有孩子的成员
输入：</p>

<blockquote><p>N M</p>

<p>ID k ID[1] ID[2] &hellip; ID[k]</p>

<p>&hellip;</p></blockquote>

<p>其中 <code>N</code>是总结点树，<code>M</code>是非叶子节点数目，接下来 M 行每一行都是 节点号 孩子个数 孩子编号列表</p>

<h3>思路</h3>

<p>输入之后构成一个图（一棵树），使用矩阵或者邻接链表都行：
类似于</p>

<p>编号 孩子列表</p>

<p>01  02  03</p>

<p>02  04</p>

<p>03  05</p>

<p>从根开始采用广度优先遍历，统计每一层没有孩子的节点即可，具体操作核心代码</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="k">struct</span> <span class="n">Node</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">id</span><span class="p">;</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">level</span><span class="p">;</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'><span class="kt">int</span> <span class="n">count</span><span class="p">[</span><span class="n">MAX_NODE</span><span class="p">];</span>
</span><span class='line'><span class="n">queue</span><span class="o">&lt;</span><span class="n">Node</span><span class="o">&gt;</span> <span class="n">q</span><span class="p">;</span>
</span><span class='line'><span class="c1">//...</span>
</span><span class='line'><span class="n">Node</span> <span class="n">root</span><span class="p">;</span>
</span><span class='line'><span class="n">root</span><span class="p">.</span><span class="n">id</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'><span class="n">root</span><span class="p">.</span><span class="n">level</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'><span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">root</span><span class="p">);</span>
</span><span class='line'><span class="k">while</span><span class="p">(</span><span class="o">!</span><span class="n">q</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="n">Node</span> <span class="n">node</span> <span class="o">=</span> <span class="n">q</span><span class="p">.</span><span class="n">front</span><span class="p">();</span>
</span><span class='line'>  <span class="n">q</span><span class="p">.</span><span class="n">pop</span><span class="p">();</span>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span><span class="n">node</span> <span class="n">has</span> <span class="n">no</span> <span class="n">child</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="n">count</span><span class="p">[</span><span class="n">node</span><span class="p">.</span><span class="n">level</span><span class="p">]</span><span class="o">++</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="k">else</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="k">for</span> <span class="n">child</span> <span class="n">of</span> <span class="n">node</span>
</span><span class='line'>      <span class="p">{</span>
</span><span class='line'>          <span class="n">Node</span> <span class="n">c</span><span class="p">;</span>
</span><span class='line'>          <span class="n">c</span><span class="p">.</span><span class="n">id</span> <span class="o">=</span> <span class="n">child</span>
</span><span class='line'>          <span class="n">c</span><span class="p">.</span><span class="n">level</span> <span class="o">=</span> <span class="n">node</span><span class="p">.</span><span class="n">level</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'>          <span class="n">q</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">c</span><span class="p">);</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h2><a href="http://pat.zju.edu.cn/contests/pat-a-practise/1005" title="1005">1005. Spell It Right (20)</a></h2>

<h3>题意</h3>

<p>输出一个数<code>N</code>的各位数字的和，但是和的每一位都需要用对应的英语输出。例如，输入12345 算出和是15，则输出 one five。需要注意的是<code>N</code>的范围是<code>[0,10^100]</code></p>

<h3>思路</h3>

<p>简单题，数字到英文的映射可以直接用数组<code>char* i2eng[] = {"zero","one",..., "nine"}</code>，使用字符串接收输入，然后求和就行了，然后再将每一位对应输出即可。</p>

<p>完整代码<a href="https://github.com/jiangdapeng/pat/blob/master/Advanced%20Level/1005.%20Spell%20It%20Right%20/(20/">请戳我</a>.cpp &ldquo;1005&rdquo;)</p>

<h2><a href="http://pat.zju.edu.cn/contests/pat-a-practise/1006" title="1006">1006. Sign In and Sign Out (25)</a></h2>

<h3>题意</h3>

<p>根据 签到以及离开的记录，找出第一个来以及最后一个走的人</p>

<h3>思路</h3>

<p>简单的题，遍历所有记录，分别记住签到最早的人以及离开最晚的人即可，连排序都用不上</p>

<p>完整代码<a href="https://github.com/jiangdapeng/pat/blob/master/Advanced%20Level/1006.%20Sign%20In%20and%20Sign%20Out%20(\25).cpp" title="1006">请戳我</a></p>

<h2><a href="http://pat.zju.edu.cn/contests/pat-a-practise/1007" title="1007">1007. Maximum Subsequence Sum (25)</a></h2>

<h3>题意</h3>

<p>给定一个整数序列，求其中的一个连续子序列，该子序列中元素的和是所有连续子序列中最大的，输出和以及序列开始、结束的元素。题目规定，如果序列里的值都是负数，则最大和定义为<code>0</code>，输出整个序列开始、结束元素。</p>

<h3>思路</h3>

<p>非常经典的一个题目，记得当年算法基础教材里面就讲了这道题目，而且是讲了三个还是四个方法，复杂度从最高O(N<sup>3</sup>)到最低O(N)，当真把我给镇住了！这算法带来的效率提高真不是一般厉害。
O(N）复杂度的算法核心如下</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="n">max_sum</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span><span class='line'><span class="n">sum</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'><span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">n</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="n">sum</span> <span class="o">+=</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
</span><span class='line'>  <span class="n">sum</span> <span class="o">=</span> <span class="n">max</span><span class="p">(</span><span class="n">sum</span><span class="p">,</span><span class="mi">0</span><span class="p">);</span>
</span><span class='line'>  <span class="n">max_sum</span> <span class="o">=</span> <span class="n">max</span><span class="p">(</span><span class="n">max_sum</span><span class="p">,</span> <span class="n">sum</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>解释起来也比较好理解：</p>

<ol>
<li>如果加上当前元素后，<code>sum &lt; 0</code>，那么得到当前和的这一序列肯定不属于所求序列的一部分，因为加上一个负值，和肯定是变小的。因此将sum重置为<code>0</code>，接下去继续找；</li>
<li>每一步都需要将最新的<code>sum</code>与已知的<code>max_sum</code>比较，如果新的和已经更大了，则更新<code>max_sum</code>的值。</li>
</ol>


<p>当然，要完成这道题，代码要稍微复杂点，比如要注意序列里是否有非负数出现，在更新<code>sum 或者 max_sum</code>的时候，同时需要记住对应的序列开始结束的位置。
完整代码<a href="https://github.com/jiangdapeng/pat/blob/master/Advanced%20Level/1007.%20Maximum%20Subsequence%20Sum%20(25).cpp" title="1007">请戳我</a></p>

<h2><a href="http://pat.zju.edu.cn/contests/pat-a-practise/1008" title="1008">1008. Elevator (20)</a></h2>

<h3>题意</h3>

<p>给定一串电梯的请求序列，计算电梯完成所有请求所需要的时间。已知电梯上移一层楼需要 6s，下移一层需要 4s，每次停下来需要花 5s。</p>

<h3>思路</h3>

<p>就是简单的模拟题，按照给定的顺序模拟电梯运行，计算相应的时间花费。</p>

<p>完整代码<a href="https://github.com/jiangdapeng/pat/blob/master/Advanced%20Level/1008.%20Elevator%20(20).cpp" title="1008">请戳我</a></p>

<h2><a href="http://pat.zju.edu.cn/contests/pat-a-practise/1009" title="1009">1009. Product of Polynomials (25)</a></h2>

<h3>题意</h3>

<p>计算多项式的乘积</p>

<h3>思路</h3>

<p>前面有一道题<a href="http://pat.zju.edu.cn/contests/pat-a-practise/1002" title="1002. A+B for Polynomials (25)">1002. A+B for Polynomials (25)</a> 已经做了多项式的加法操作，再定义一个多项式与单项相乘的方法，然后将一个多项式的每一个项与另外一个多项式相乘，将结果再求和即可。
完整代码<a href="https://github.com/jiangdapeng/pat/blob/master/Advanced%20Level/1009.%20Product%20of%20Polynomials%20(25).cpp" title="1009">请戳我</a></p>

<h2><a href="http://pat.zju.edu.cn/contests/pat-a-practise/1010" title="1010">1010. Radix (25)</a></h2>

<h3>题意</h3>

<p>给定两个数以及其中一个数的进制，求是否存在一个进制使得另外一个数与该数的值相等。两个数的都是由<code>{0-9}</code> 以及 <code>{a-z}</code>组成</p>

<h3>思路</h3>

<p>要比较不同进制的数，最好是将其都变成十进制数来比较，因此需要一个将其他进制转换为十进制的函数。有了这个函数之后，将已知进制的数转为10进制数，然后看尝试给另外一个数设置进制，然后转为10进制，判断结果是否一致。设置进制的起始值具体看给定的数中出现的字母，比如出现的最大数是<code>a</code>，也就是至少是11进制，以此类推，没有上限。</p>

<ol>
<li>如果算出的结果相等，则结束，给出答案</li>
<li>如果偏小，则测试下一个进制</li>
<li>如果偏大，则结束，输出 Impossible</li>
</ol>


<p>这个做法有一个问题，就是可能会超时，想想，如果给定 <code>A = zzzzzzz，是37进制</code>,而<code>B = 10</code>，那么从二进制开始尝试，需要尝试的次数就非常多，很可能会超时。因此，我们不能按顺序递增进制来猜，必须跳跃性地猜。可以想到的办法就是二分法。需要尝试的基的上限是 A的值。稍微可以优化一下的是，如果B只有一位，那么值其实是确定的，这个时候可以快速判定是否存在解，而不用按照前面的方式傻乎乎的计算很多次。</p>

<p>完整代码<a href="https://github.com/jiangdapeng/pat/blob/master/Advanced%20Level/1010.%20Radix%20(25).cpp" title="1010">请戳我</a></p>

<p>【PAT 1001-1010 完】</p>

<p class='post-footer'>原文地址：<a href='http://jiangdapeng.github.io/blog/2013/10/20/pat-1001-1010-solutions/'>http://jiangdapeng.github.io/blog/2013/10/20/pat-1001-1010-solutions/</a><br/>Written by <a href='http://jiangdapeng.github.io'>Asuwill</a>&nbsp;posted at <a href='http://jiangdapeng.github.io'>http://jiangdapeng.github.io</a><br/>版权声明：自由转载-非商用-非衍生-保持署名|<a href="http://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh">Creative Commons BY-NC-ND 3.0</a></p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[markdown 常用语法]]></title>
    <link href="http://jiangdapeng.github.io/blog/2013/10/08/markdown-syntax/"/>
    <updated>2013-10-08T09:44:00+08:00</updated>
    <id>http://jiangdapeng.github.io/blog/2013/10/08/markdown-syntax</id>
    <content type="html"><![CDATA[<h1>前言</h1>

<h2>为什么我会出现在标签 pat 下</h2>

<p>说起来，是因为，我写第一篇pat题解，用 <code>bundle exec rake generate</code> 的时候，报错了</p>

<blockquote><p>Liquid Exception: comparison of Array with Array failed in page</p></blockquote>

<p>Google 了一下，有人说是“每个tag都只使用一次的时候”，这个问题就会出现。我测试了一下，还果真是如此，为了暂时解决这个问题，我只好把pat标签在这篇post里也应用一下了。</p>

<h2>标题</h2>

<h1>这是 H1</h1>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>\# 这是 H1</span></code></pre></td></tr></table></div></figure>


<h2>这是 H2</h2>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>\## 这是 H2</span></code></pre></td></tr></table></div></figure>


<h3>这是 H3</h3>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>\### 这是 H3</span></code></pre></td></tr></table></div></figure>


<h4>这是 H4</h4>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>\#### 这是 H4</span></code></pre></td></tr></table></div></figure>


<h2>区块引用</h2>

<blockquote><p>区块引用1</p>

<blockquote><p>区块引用2</p></blockquote>

<p>回到引用1</p>

<h2>这是一个标题</h2>

<ol>
<li>列表1</li>
<li>列表2</li>
</ol>


<p>给出一些例子代码：</p>

<p>  return shell_exec(&ldquo;echo $input | $markdown_script&rdquo;);</p></blockquote>

<h2>列表</h2>

<h3>无序列表</h3>

<ul>
<li>师叔</li>
<li>师太</li>
<li>春哥</li>
<li>马老师</li>
<li>主席</li>
<li>女王大人</li>
<li>亲王大人</li>
</ul>


<h3>有序列表</h3>

<ol>
<li>师叔女人1号</li>
<li>师叔女人2号</li>
<li>师叔女人3号</li>
<li>。。。</li>
</ol>


<h2>代码区块</h2>

<p>这是普通的段落</p>

<pre><code>这是代码块（行首4个空格或者1个制表符）
</code></pre>

<h2>区段元素</h2>

<p class='post-footer'>原文地址：<a href='http://jiangdapeng.github.io/blog/2013/10/08/markdown-syntax/'>http://jiangdapeng.github.io/blog/2013/10/08/markdown-syntax/</a><br/>Written by <a href='http://jiangdapeng.github.io'>Asuwill</a>&nbsp;posted at <a href='http://jiangdapeng.github.io'>http://jiangdapeng.github.io</a><br/>版权声明：自由转载-非商用-非衍生-保持署名|<a href="http://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh">Creative Commons BY-NC-ND 3.0</a></p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[江大鹏的第一篇博客]]></title>
    <link href="http://jiangdapeng.github.io/blog/2013/10/07/first-octopress-blog/"/>
    <updated>2013-10-07T20:12:00+08:00</updated>
    <id>http://jiangdapeng.github.io/blog/2013/10/07/first-octopress-blog</id>
    <content type="html"><![CDATA[<p class='post-footer'>原文地址：<a href='http://jiangdapeng.github.io/blog/2013/10/07/first-octopress-blog/'>http://jiangdapeng.github.io/blog/2013/10/07/first-octopress-blog/</a><br/>Written by <a href='http://jiangdapeng.github.io'>Asuwill</a>&nbsp;posted at <a href='http://jiangdapeng.github.io'>http://jiangdapeng.github.io</a><br/>版权声明：自由转载-非商用-非衍生-保持署名|<a href="http://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh">Creative Commons BY-NC-ND 3.0</a></p>

]]></content>
  </entry>
  
</feed>
