﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-The Way of C++ -随笔分类-ACM</title><link>http://www.cppblog.com/koson/category/12290.html</link><description /><language>zh-cn</language><lastBuildDate>Thu, 23 Sep 2010 17:22:24 GMT</lastBuildDate><pubDate>Thu, 23 Sep 2010 17:22:24 GMT</pubDate><ttl>60</ttl><item><title>海量数据面试题整理（转）</title><link>http://www.cppblog.com/koson/archive/2010/09/23/127442.html</link><dc:creator>koson</dc:creator><author>koson</author><pubDate>Thu, 23 Sep 2010 12:42:00 GMT</pubDate><guid>http://www.cppblog.com/koson/archive/2010/09/23/127442.html</guid><wfw:comment>http://www.cppblog.com/koson/comments/127442.html</wfw:comment><comments>http://www.cppblog.com/koson/archive/2010/09/23/127442.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/koson/comments/commentRss/127442.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/koson/services/trackbacks/127442.html</trackback:ping><description><![CDATA[<p><strong>1. 给定a、b两个文件，各存放50<a name=baidusnap1></a><strong style="BACKGROUND-COLOR: #a0ffff; COLOR: black">亿个url</strong>，每个url各占64字节，内存限制是4G，让你找出a、b文件共同的url？</strong></p>
<p>方案1：可以估计每个文件安的大小为50G&#215;64=320G，远远大于内存限制的4G。所以不可能将其完全加载到内存中<a name=baidusnap4></a><strong style="BACKGROUND-COLOR: #ff66ff; COLOR: black">处理</strong>。考虑采取分而治之的<a name=baidusnap5></a><strong style="BACKGROUND-COLOR: #880000; COLOR: white">方法</strong>。</p>
<p>s 遍历文件a，对每个url求取<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image002_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image002 border=0 alt=clip_image002 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image002_thumb.png" width=103 height=21></a>，然后根据所取得的值将url分别存储到<a name=baidusnap0></a><strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>0个小文件（记为<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image004_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image004 border=0 alt=clip_image004 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image004_thumb.png" width=83 height=21></a>）中。这样每个小文件的大约为300M。</p>
<p>s 遍历文件b，采取和a相同的方式将url分别存储到<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>0各小文件（记为<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image006_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image006 border=0 alt=clip_image006 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image006_thumb.png" width=81 height=21></a>）。这样<strong style="BACKGROUND-COLOR: #ff66ff; COLOR: black">处理</strong>后，所有可能相同的url都在对应的小文件（<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image008_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image008 border=0 alt=clip_image008 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image008_thumb.png" width=179 height=21></a>）中，不对应的小文件不可能有相同的url。然后我们只要求出<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>0对小文件中相同的url即可。</p>
<p>s 求每对小文件中相同的url时，可以把其中一个小文件的url存储到hash_set中。然后遍历另一个小文件的每个url，看其是否在刚才构建的hash_set中，如果是，那么就是共同的url，存到文件里面就可以了。</p>
<p>方案2：如果允许有一定的错误率，可以使用Bloom filter，4G内存大概可以表示340亿bit。将其中一个文件中的url使用Bloom filter映射为这340亿bit，然后挨个读取另外一个文件的url，检查是否与Bloom filter，如果是，那么该url应该是共同的url（注意会有一定的错误率）。</p>
<p><strong>2. 有10个文件，每个文件1G，每个文件的每一行存放的都是用户的query，每个文件的query都可能重复。要求你按照query的频度排序。</strong></p>
<p>方案1：</p>
<p>s 顺序读取10个文件，按照hash(query)%10的结果将query写入到另外10个文件（记为<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image010_3.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image010 border=0 alt=clip_image010 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image010_thumb.png" width=72 height=21></a>）中。这样新生成的文件每个的大小大约也1G（假设hash函数是随机的）。</p>
<p>s 找一台内存在2G左右的机器，依次对<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image010%5B1%5D.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image010[1] border=0 alt=clip_image010[1] src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image010%5B1%5D_thumb.png" width=72 height=21></a>用hash_map(query, query_count)来统计每个query出现的次数。利用快速/堆/归并排序按照出现次数进行排序。将排序好的query和对应的query_cout输出到文件中。这样得到了10个排好序的文件（记为<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image012_3.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image012 border=0 alt=clip_image012 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image012_thumb.png" width=75 height=21></a>）。</p>
<p>s 对<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image012%5B1%5D.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image012[1] border=0 alt=clip_image012[1] src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image012%5B1%5D_thumb.png" width=75 height=21></a>这10个文件进行归并排序（内排序与外排序相结合）。</p>
<p>方案2：</p>
<p>一般query的总量是有限的，只是重复的次数比较多而已，可能对于所有的query，一次性就可以加入到内存了。这样，我们就可以采用trie树/hash_map等直接来统计每个query出现的次数，然后按出现次数做快速/堆/归并排序就可以了。</p>
<p>方案3：</p>
<p>与方案1类似，但在做完hash，分成多个文件后，可以交给多个文件来<strong style="BACKGROUND-COLOR: #ff66ff; COLOR: black">处理</strong>，采用分布式的架构来<strong style="BACKGROUND-COLOR: #ff66ff; COLOR: black">处理</strong>（比如MapReduce），最后再进行合并。</p>
<p><strong>3. 有一个1G大小的一个文件，里面每一行是一个词，词的大小不超过16字节，内存限制大小是1M。返回频数最高的<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>个词。</strong></p>
<p>方案1：顺序读文件中，对于每个词x，取<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image014_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image014 border=0 alt=clip_image014 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image014_thumb.png" width=91 height=21></a>，然后按照该值存到5000个小文件（记为<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image016_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image016 border=0 alt=clip_image016 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image016_thumb.png" width=87 height=21></a>）中。这样每个文件大概是200k左右。如果其中的有的文件超过了1M大小，还可以按照类似的<strong style="BACKGROUND-COLOR: #880000; COLOR: white">方法</strong>继续往下分，知道分解得到的小文件的大小都不超过1M。对每个小文件，统计每个文件中出现的词以及相应的频率（可以采用trie树/hash_map等），并取出出现频率最大的<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>个词（可以用含<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>个结点的最小堆），并把<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>词及相应的频率存入文件，这样又得到了5000个文件。下一步就是把这5000个文件进行归并（类似与归并排序）的过程了。</p>
<p><strong>4. 海量日志数据，提取出某日访问百度次数最多的那个IP。</strong></p>
<p>方案1：首先是这一天，并且是访问百度的日志中的IP取出来，逐个写入到一个大文件中。注意到IP是32位的，最多有<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image018_3.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image018 border=0 alt=clip_image018 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image018_thumb.png" width=20 height=21></a>个IP。同样可以采用映射的<strong style="BACKGROUND-COLOR: #880000; COLOR: white">方法</strong>，比如模<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>0，把整个大文件映射为<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>0个小文件，再找出每个小文中出现频率最大的IP（可以采用hash_map进行频率统计，然后再找出频率最大的几个）及相应的频率。然后再在这<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>0个最大的IP中，找出那个频率最大的IP，即为所求。</p>
<p><strong>5. 在2.5亿个整数中找出不重复的整数，内存不足以容纳这2.5亿个整数。</strong></p>
<p>方案1：采用2-Bitmap（每个数分配2bit，00表示不存在，01表示出现一次，10表示多次，11无意义）进行，共需内存<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image020_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image020 border=0 alt=clip_image020 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image020_thumb.png" width=106 height=21></a>内存，还可以接受。然后扫描这2.5亿个整数，查看Bitmap中相对应位，如果是00变01，01变10，10保持不变。所描完事后，查看bitmap，把对应位是01的整数输出即可。</p>
<p>方案2：也可采用上题类似的<strong style="BACKGROUND-COLOR: #880000; COLOR: white">方法</strong>，进行划分小文件的<strong style="BACKGROUND-COLOR: #880000; COLOR: white">方法</strong>。然后在小文件中找出不重复的整数，并排序。然后再进行归并，注意去除重复的元素。</p>
<p><strong>6. 海量数据分布在<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>台电脑中，想个办法高校统计出这批数据的TOP10。</strong></p>
<p>方案1：</p>
<p>s 在每台电脑上求出TOP10，可以采用包含10个元素的堆完成（TOP10小，用最大堆，TOP10大，用最小堆）。比如求TOP10大，我们首先取前10个元素调整成最小堆，如果发现，然后扫描后面的数据，并与堆顶元素比较，如果比堆顶元素大，那么用该元素替换堆顶，然后再调整为最小堆。最后堆中的元素就是TOP10大。</p>
<p>s 求出每台电脑上的TOP10后，然后把这<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>台电脑上的TOP10组合起来，共<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>0个数据，再利用上面类似的<strong style="BACKGROUND-COLOR: #880000; COLOR: white">方法</strong>求出TOP10就可以了。</p>
<p><strong>7. 怎么在海量数据中找出重复次数最多的一个？</strong></p>
<p>方案1：先做hash，然后求模映射为小文件，求出每个小文件中重复次数最多的一个，并记录重复次数。然后找出上一步求出的数据中重复次数最多的一个就是所求（具体参考前面的题）。</p>
<p><strong>8. 上千万或上亿数据（有重复），统计其中出现次数最多的钱N个数据。</strong></p>
<p>方案1：上千万或上亿的数据，现在的机器的内存应该能存下。所以考虑采用hash_map/搜索二叉树/红黑树等来进行统计次数。然后就是取出前N个出现次数最多的数据了，可以用第6题提到的堆机制完成。</p>
<p><strong>9. <strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>0万字符串，其中有些是重复的，需要把重复的全部去掉，保留没有重复的字符串。请怎么设计和实现？</strong></p>
<p>方案1：这题用trie树比较合适，hash_map也应该能行。</p>
<p><strong>10. 一个文本文件，大约有一万行，每行一个词，要求统计出其中最频繁出现的前10个词，请给出思想，给出时间复杂度分析。</strong></p>
<p>方案1：这题是考虑时间效率。用trie树统计每个词出现的次数，时间复杂度是O(n*le)（le表示单词的平准长度）。然后是找出出现最频繁的前10个词，可以用堆来实现，前面的题中已经讲到了，时间复杂度是O(n*lg10)。所以总的时间复杂度，是O(n*le)与O(n*lg10)中较大的哪一个。</p>
<p><strong>11. 一个文本文件，找出前10个经常出现的词，但这次文件比较长，说是上亿行或十亿行，总之无法一次读入内存，问最优解。</strong></p>
<p>方案1：首先根据用hash并求模，将文件分解为多个小文件，对于单个文件利用上题的<strong style="BACKGROUND-COLOR: #880000; COLOR: white">方法</strong>求出每个文件件中10个最常出现的词。然后再进行归并<strong style="BACKGROUND-COLOR: #ff66ff; COLOR: black">处理</strong>，找出最终的10个最常出现的词。</p>
<p><strong>12. <strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>w个数中找出最大的<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>个数。</strong></p>
<p>方案1：在前面的题中，我们已经提到了，用一个含<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>个元素的最小堆完成。复杂度为O(<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>w*lg<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>)。</p>
<p>方案2：采用快速排序的思想，每次分割之后只考虑比轴大的一部分，知道比轴大的一部分在比<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>多的时候，采用传统排序算法排序，取前<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>个。复杂度为O(<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>w*<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>)。</p>
<p>方案3：采用局部淘汰法。选取前<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>个元素，并排序，记为序列L。然后一次扫描剩余的元素x，与排好序的<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>个元素中最小的元素比，如果比这个最小的要大，那么把这个最小的元素删除，并把x利用插入排序的思想，插入到序列L中。依次循环，知道扫描了所有的元素。复杂度为O(<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>w*<strong style="BACKGROUND-COLOR: #ffff66; COLOR: black">100</strong>)。</p>
<p><strong>13. 寻找热门查询：</strong></p>
<p>搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来，每个查询串的长度为1-255字节。假设目前有一千万个记录，这些查询串的重复读比较高，虽然总数是1千万，但是如果去除重复和，不超过3百万个。一个查询串的重复度越高，说明查询它的用户越多，也就越热门。请你统计最热门的10个查询串，要求使用的内存不能超过1G。</p>
<p>(1) 请描述你解决这个问题的思路；</p>
<p>(2) 请给出主要的<strong style="BACKGROUND-COLOR: #ff66ff; COLOR: black">处理</strong>流程，算法，以及算法的复杂度。</p>
<p>方案1：采用trie树，关键字域存该查询串出现的次数，没有出现为0。最后用10个元素的最小推来对出现频率进行排序。</p>
<p><strong>14. 一共有N个机器，每个机器上有N个数。每个机器最多存O(N)个数并对它们操作。如何找到<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image022_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image022 border=0 alt=clip_image022 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image022_thumb.png" width=16 height=21></a>个数中的中数？</strong></p>
<p>方案1：先大体估计一下这些数的范围，比如这里假设这些数都是32位无符号整数（共有<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image018%5B1%5D.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image018[1] border=0 alt=clip_image018[1] src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image018%5B1%5D_thumb.png" width=20 height=21></a>个）。我们把0到<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image024_3.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image024 border=0 alt=clip_image024 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image024_thumb.png" width=44 height=21></a>的整数划分为N个范围段，每个段包含<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image026_3.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image026 border=0 alt=clip_image026 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image026_thumb.png" width=16 height=42></a>个整数。比如，第一个段位0到<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image028_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image028 border=0 alt=clip_image028 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image028_thumb.png" width=40 height=42></a>，第二段为<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image026%5B1%5D.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image026[1] border=0 alt=clip_image026[1] src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image026%5B1%5D_thumb.png" width=16 height=42></a>到<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image030_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image030 border=0 alt=clip_image030 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image030_thumb.png" width=40 height=42></a>，&#8230;，第N个段为<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image032_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image032 border=0 alt=clip_image032 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image032_thumb.png" width=45 height=42></a>到<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image024%5B1%5D.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image024[1] border=0 alt=clip_image024[1] src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image024%5B1%5D_thumb.png" width=44 height=21></a>。然后，扫描每个机器上的N个数，把属于第一个区段的数放到第一个机器上，属于第二个区段的数放到第二个机器上，&#8230;，属于第N个区段的数放到第N个机器上。注意这个过程每个机器上存储的数应该是O(N)的。下面我们依次统计每个机器上数的个数，一次累加，直到找到第k个机器，在该机器上累加的数大于或等于<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image034_4.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image034 border=0 alt=clip_image034 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image034_thumb.png" width=13 height=42></a>，而在第k-1个机器上的累加数小于<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image034%5B1%5D.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image034[1] border=0 alt=clip_image034[1] src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image034%5B1%5D_thumb.png" width=13 height=42></a>，并把这个数记为x。那么我们要找的中位数在第k个机器中，排在第<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image036_3.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image036 border=0 alt=clip_image036 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image036_thumb.png" width=37 height=42></a>位。然后我们对第k个机器的数排序，并找出第<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image036%5B1%5D.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image036[1] border=0 alt=clip_image036[1] src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image036%5B1%5D_thumb.png" width=37 height=42></a>个数，即为所求的中位数。复杂度是<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image038_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image038 border=0 alt=clip_image038 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image038_thumb.png" width=38 height=21></a>的。</p>
<p>方案2：先对每台机器上的数进行排序。排好序后，我们采用归并排序的思想，将这N个机器上的数归并起来得到最终的排序。找到第<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image034%5B2%5D.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image034[2] border=0 alt=clip_image034[2] src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image034%5B2%5D_thumb.png" width=13 height=42></a>个便是所求。复杂度是<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image040_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image040 border=0 alt=clip_image040 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image040_thumb.png" width=69 height=21></a>的。</p>
<p><strong>15. 最大间隙问题</strong></p>
<p>给定n个实数<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image042_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image042 border=0 alt=clip_image042 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image042_thumb.png" width=90 height=21></a>，求着n个实数在实轴上向量2个数之间的最大差值，要求线性的时间算法。</p>
<p>方案1：最先想到的<strong style="BACKGROUND-COLOR: #880000; COLOR: white">方法</strong>就是先对这n个数据进行排序，然后一遍扫描即可确定相邻的最大间隙。但该<strong style="BACKGROUND-COLOR: #880000; COLOR: white">方法</strong>不能满足线性时间的要求。故采取如下<strong style="BACKGROUND-COLOR: #880000; COLOR: white">方法</strong>：</p>
<p>s 找到n个数据中最大和最小数据max和min。</p>
<p>s 用n-2个点等分区间[min, max]，即将[min, max]等分为n-1个区间（前闭后开区间），将这些区间看作桶，编号为<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image044_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image044 border=0 alt=clip_image044 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image044_thumb.png" width=115 height=21></a>，且桶<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image046_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image046 border=0 alt=clip_image046 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image046_thumb.png" width=8 height=25></a>的上界和桶i+1的下届相同，即每个桶的大小相同。每个桶的大小为：<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image048_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image048 border=0 alt=clip_image048 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image048_thumb.png" width=139 height=42></a>。实际上，这些桶的边界构成了一个等差数列（首项为min，公差为<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image050_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image050 border=0 alt=clip_image050 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image050_thumb.png" width=89 height=21></a>），且认为将min放入第一个桶，将max放入第n-1个桶。</p>
<p>s 将n个数放入n-1个桶中：将每个元素<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image052_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image052 border=0 alt=clip_image052 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image052_thumb.png" width=20 height=21></a>分配到某个桶（编号为index），其中<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image054_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image054 border=0 alt=clip_image054 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image054_thumb.png" width=152 height=42></a>，并求出分到每个桶的最大最小数据。</p>
<p>s 最大间隙：除最大最小数据max和min以外的n-2个数据放入n-1个桶中，由抽屉原理可知至少有一个桶是空的，又因为每个桶的大小相同，所以最大间隙不会在同一桶中出现，一定是某个桶的上界和气候某个桶的下界之间隙，且该量筒之间的桶（即便好在该连个便好之间的桶）一定是空桶。也就是说，最大间隙在桶i的上界和桶j的下界之间产生<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image056_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image056 border=0 alt=clip_image056 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image056_thumb.png" width=50 height=21></a>。一遍扫描即可完成。</p>
<p><strong>16. 将多个集合合并成没有交集的集合：给定一个字符串的集合，格式如：<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image058_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image058 border=0 alt=clip_image058 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image058_thumb.png" width=240 height=15></a>。要求将其中交集不为空的集合合并，要求合并完成的集合之间无交集，例如上例应输出<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image060_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image060 border=0 alt=clip_image060 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image060_thumb.png" width=240 height=20></a>。</strong></p>
<p>(1) 请描述你解决这个问题的思路；</p>
<p>(2) 给出主要的<strong style="BACKGROUND-COLOR: #ff66ff; COLOR: black">处理</strong>流程，算法，以及算法的复杂度；</p>
<p>(3) 请描述可能的改进。</p>
<p>方案1：采用并查集。首先所有的字符串都在单独的并查集中。然后依扫描每个集合，顺序合并将两个相邻元素合并。例如，对于<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image062_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image062 border=0 alt=clip_image062 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image062_thumb.png" width=88 height=21></a>，首先查看aaa和bbb是否在同一个并查集中，如果不在，那么把它们所在的并查集合并，然后再看bbb和ccc是否在同一个并查集中，如果不在，那么也把它们所在的并查集合并。接下来再扫描其他的集合，当所有的集合都扫描完了，并查集代表的集合便是所求。复杂度应该是O(NlgN)的。改进的话，首先可以记录每个节点的根结点，改进查询。合并的时候，可以把大的和小的进行合，这样也减少复杂度。</p>
<p><strong>17. 最大子序列与最大子矩阵问题</strong></p>
<p>数组的最大子序列问题：给定一个数组，其中元素有正，也有负，找出其中一个连续子序列，使和最大。</p>
<p>方案1：这个问题可以动态规划的思想解决。设<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image064_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image064 border=0 alt=clip_image064 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image064_thumb.png" width=21 height=21></a>表示以第i个元素<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image066_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image066 border=0 alt=clip_image066 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image066_thumb.png" width=21 height=21></a>结尾的最大子序列，那么显然<a href="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image068_2.png"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=clip_image068 border=0 alt=clip_image068 src="http://images.cnblogs.com/cnblogs_com/youwang/WindowsLiveWriter/1340f2e6fa8e_D5D1/clip_image068_thumb.png" width=240 height=20></a>。基于这一点可以很快用代码实现。</p>
<p>最大子矩阵问题：给定一个矩阵（二维数组），其中数据有大有小，请找一个子矩阵，使得子矩阵的和最大，并输出这个和。</p>
<p>方案1：可以采用与最大子序列类似的思想来解决。如果我们确定了选择第i列和第j列之间的元素，那么在这个范围内，其实就是一个最大子序列问题。如何确定第i列和第j列可以词用暴搜的<strong style="BACKGROUND-COLOR: #880000; COLOR: white">方法</strong>进行。</p>
<img src ="http://www.cppblog.com/koson/aggbug/127442.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/koson/" target="_blank">koson</a> 2010-09-23 20:42 <a href="http://www.cppblog.com/koson/archive/2010/09/23/127442.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>POJ 1523 无向图的割点</title><link>http://www.cppblog.com/koson/archive/2010/04/28/113901.html</link><dc:creator>koson</dc:creator><author>koson</author><pubDate>Wed, 28 Apr 2010 12:57:00 GMT</pubDate><guid>http://www.cppblog.com/koson/archive/2010/04/28/113901.html</guid><wfw:comment>http://www.cppblog.com/koson/comments/113901.html</wfw:comment><comments>http://www.cppblog.com/koson/archive/2010/04/28/113901.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/koson/comments/commentRss/113901.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/koson/services/trackbacks/113901.html</trackback:ping><description><![CDATA[&nbsp;看了无向图的割点，割边的东西，顺便做了这道题。题目要求出割点以及除去割点后的连通子图的数量。求割点的方法利用深度优先搜索的子数，以及记录结点的访问时间以及结点所能到达的最低祖先，然后对这两个数进行比较从而确定结点是否是割点，求出割点后，要求出此割点去掉后连通子图的数量，一种方法是，对每一个割点，对它的相邻顶点分别进行一次深搜，每搜一次结果加1。但从求割点的过程中分析可知，不通过这样的遍历就可以方便的得到这个结果。用tag[i]标记结点i是否为割点，对于根结点，当搜索它的第一个子树时，由于子树数为1，所以tag[i]仍为零，当每搜索其它一棵子树时，都可以判定根结点是割点，那么tag[i]++, 所以根结点如果是割的情况下它所能形成的连通子图数目为tag[i]+1； 对于非根结点，当第一次遍历到这个结点时，这个结点还不能判断为割点，之后对此结点的每一棵子树，如果能判定i是割点，则tag[i]++, 最后连通子图数还要加上第一次遍历到这个结点时所形成的图，所以总的连通子图数为tag[i]+1。另外此题的结点不一定是连续的。只有1000多个结点，可以直接用邻接矩阵，但要占用比较多的空间。<br>附上代码：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">#include</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">stdio.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;">#include</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">string</span><span style="color: #000000;">.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;N&nbsp;1050</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;w[N][N];<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;n;<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;m;<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;time;<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;dis[N];<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;low[N];<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;tag[N];<br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;dfs(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;v,</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;prt)<br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;time</span><span style="color: #000000;">++</span><span style="color: #000000;">;<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;dis[v]</span><span style="color: #000000;">=</span><span style="color: #000000;">low[v]</span><span style="color: #000000;">=</span><span style="color: #000000;">time;<br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;child</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i;<br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">(i</span><span style="color: #000000;">=</span><span style="color: #000000;">m;i</span><span style="color: #000000;">&lt;=</span><span style="color: #000000;">n;</span><span style="color: #000000;">++</span><span style="color: #000000;">i)<br></span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(w[v][i]</span><span style="color: #000000;">==</span><span style="color: #000000;">0</span><span style="color: #000000;">)&nbsp;</span><span style="color: #0000ff;">continue</span><span style="color: #000000;">;<br></span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(i</span><span style="color: #000000;">!=</span><span style="color: #000000;">prt</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">dis[i]</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">0</span><span style="color: #000000;">)<br></span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(dis[i]</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">low[v])<br></span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;low[v]</span><span style="color: #000000;">=</span><span style="color: #000000;">dis[i];<br></span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(dis[i]</span><span style="color: #000000;">==</span><span style="color: #000000;">0</span><span style="color: #000000;">)<br></span><span style="color: #008080;">25</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">26</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;child</span><span style="color: #000000;">++</span><span style="color: #000000;">;<br></span><span style="color: #008080;">27</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dfs(i,v);<br></span><span style="color: #008080;">28</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(low[i]</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">low[v])<br></span><span style="color: #008080;">29</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;low[v]</span><span style="color: #000000;">=</span><span style="color: #000000;">low[i];<br></span><span style="color: #008080;">30</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">((v</span><span style="color: #000000;">!=</span><span style="color: #000000;">m</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">dis[v]</span><span style="color: #000000;">&lt;=</span><span style="color: #000000;">low[i])</span><span style="color: #000000;">||</span><span style="color: #000000;">(child</span><span style="color: #000000;">&gt;=</span><span style="color: #000000;">2</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">v</span><span style="color: #000000;">==</span><span style="color: #000000;">m))<br></span><span style="color: #008080;">31</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tag[v]</span><span style="color: #000000;">++</span><span style="color: #000000;">;<br></span><span style="color: #008080;">32</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">33</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">34</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">35</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;input()<br></span><span style="color: #008080;">36</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">37</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;a,b;<br></span><span style="color: #008080;">38</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;cur</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">39</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">(scanf(</span><span style="color: #000000;">"</span><span style="color: #000000;">%d</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">a)</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">a</span><span style="color: #000000;">!=</span><span style="color: #000000;">0</span><span style="color: #000000;">)<br></span><span style="color: #008080;">40</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">41</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scanf(</span><span style="color: #000000;">"</span><span style="color: #000000;">%d</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">b);<br></span><span style="color: #008080;">42</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">43</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m</span><span style="color: #000000;">=</span><span style="color: #000000;">1005</span><span style="color: #000000;">;<br></span><span style="color: #008080;">44</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memset(w,</span><span style="color: #000000;">0</span><span style="color: #000000;">,</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(w));<br></span><span style="color: #008080;">45</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;w[a][b]</span><span style="color: #000000;">=</span><span style="color: #000000;">w[b][a]</span><span style="color: #000000;">=</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br></span><span style="color: #008080;">46</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(a</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">n)&nbsp;n</span><span style="color: #000000;">=</span><span style="color: #000000;">a;<br></span><span style="color: #008080;">47</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(b</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">n)&nbsp;n</span><span style="color: #000000;">=</span><span style="color: #000000;">b;<br></span><span style="color: #008080;">48</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(a</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">m)&nbsp;m</span><span style="color: #000000;">=</span><span style="color: #000000;">a;<br></span><span style="color: #008080;">49</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(b</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">m)&nbsp;m</span><span style="color: #000000;">=</span><span style="color: #000000;">b;<br></span><span style="color: #008080;">50</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">(scanf(</span><span style="color: #000000;">"</span><span style="color: #000000;">%d</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">a)</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">a</span><span style="color: #000000;">!=</span><span style="color: #000000;">0</span><span style="color: #000000;">)<br></span><span style="color: #008080;">51</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">52</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scanf(</span><span style="color: #000000;">"</span><span style="color: #000000;">%d</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">b);<br></span><span style="color: #008080;">53</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;w[a][b]</span><span style="color: #000000;">=</span><span style="color: #000000;">w[b][a]</span><span style="color: #000000;">=</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br></span><span style="color: #008080;">54</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(a</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">n)&nbsp;n</span><span style="color: #000000;">=</span><span style="color: #000000;">a;<br></span><span style="color: #008080;">55</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(b</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">n)&nbsp;n</span><span style="color: #000000;">=</span><span style="color: #000000;">b;<br></span><span style="color: #008080;">56</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(a</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">m)&nbsp;m</span><span style="color: #000000;">=</span><span style="color: #000000;">a;<br></span><span style="color: #008080;">57</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(b</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">m)&nbsp;m</span><span style="color: #000000;">=</span><span style="color: #000000;">b;<br></span><span style="color: #008080;">58</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">59</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memset(tag,</span><span style="color: #000000;">0</span><span style="color: #000000;">,</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(tag));<br></span><span style="color: #008080;">60</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memset(dis,</span><span style="color: #000000;">0</span><span style="color: #000000;">,</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(dis));<br></span><span style="color: #008080;">61</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memset(low,</span><span style="color: #000000;">0</span><span style="color: #000000;">,</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(low));<br></span><span style="color: #008080;">62</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">63</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dfs(m,</span><span style="color: #000000;">0</span><span style="color: #000000;">);<br></span><span style="color: #008080;">64</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i,j,bb;<br></span><span style="color: #008080;">65</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bb</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">66</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">Network&nbsp;#%d\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">++</span><span style="color: #000000;">cur);<br></span><span style="color: #008080;">67</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">68</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">(i</span><span style="color: #000000;">=</span><span style="color: #000000;">m;i</span><span style="color: #000000;">&lt;=</span><span style="color: #000000;">n;</span><span style="color: #000000;">++</span><span style="color: #000000;">i)<br></span><span style="color: #008080;">69</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">70</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(tag[i])<br></span><span style="color: #008080;">71</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">72</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bb</span><span style="color: #000000;">=</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br></span><span style="color: #008080;">73</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;&nbsp;SPF&nbsp;node&nbsp;%d&nbsp;leaves&nbsp;%d&nbsp;subnets\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,i,tag[i]</span><span style="color: #000000;">+</span><span style="color: #000000;">1</span><span style="color: #000000;">);<br></span><span style="color: #008080;">74</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">75</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">76</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">77</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(</span><span style="color: #000000;">!</span><span style="color: #000000;">bb)&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;&nbsp;No&nbsp;SPF&nbsp;nodes\n</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br></span><span style="color: #008080;">78</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">\n</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br></span><span style="color: #008080;">79</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">80</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">81</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">82</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main()<br></span><span style="color: #008080;">83</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">84</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;input();<br></span><span style="color: #008080;">85</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br></span><span style="color: #008080;">86</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">87</span>&nbsp;<span style="color: #000000;"></span></div>
<br><br><img src ="http://www.cppblog.com/koson/aggbug/113901.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/koson/" target="_blank">koson</a> 2010-04-28 20:57 <a href="http://www.cppblog.com/koson/archive/2010/04/28/113901.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>有向图强连通分量的三种算法</title><link>http://www.cppblog.com/koson/archive/2010/04/27/113694.html</link><dc:creator>koson</dc:creator><author>koson</author><pubDate>Tue, 27 Apr 2010 04:08:00 GMT</pubDate><guid>http://www.cppblog.com/koson/archive/2010/04/27/113694.html</guid><wfw:comment>http://www.cppblog.com/koson/comments/113694.html</wfw:comment><comments>http://www.cppblog.com/koson/archive/2010/04/27/113694.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/koson/comments/commentRss/113694.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/koson/services/trackbacks/113694.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: document.body.oncopy = function() {if (window.clipboardData) {setTimeout(function() {var text = clipboardData.getData("text");if (text && text.length > 300) {text = text + "\r\n\n本文来自CSDN博客，...&nbsp;&nbsp;<a href='http://www.cppblog.com/koson/archive/2010/04/27/113694.html'>阅读全文</a><img src ="http://www.cppblog.com/koson/aggbug/113694.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/koson/" target="_blank">koson</a> 2010-04-27 12:08 <a href="http://www.cppblog.com/koson/archive/2010/04/27/113694.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>四道有趣的单链表面试题（单链表反序、找出链表的中间元素、链表排序、判断一个单链表是否有环） (转)</title><link>http://www.cppblog.com/koson/archive/2010/04/21/113142.html</link><dc:creator>koson</dc:creator><author>koson</author><pubDate>Wed, 21 Apr 2010 07:50:00 GMT</pubDate><guid>http://www.cppblog.com/koson/archive/2010/04/21/113142.html</guid><wfw:comment>http://www.cppblog.com/koson/comments/113142.html</wfw:comment><comments>http://www.cppblog.com/koson/archive/2010/04/21/113142.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/koson/comments/commentRss/113142.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/koson/services/trackbacks/113142.html</trackback:ping><description><![CDATA[<span>以下给出链表结点的数据结构：</span><br>
<div><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span>1</span>&nbsp;<span>&nbsp;typedef&nbsp;</span><span>struct</span><span>&nbsp;_list_node<br></span><span>2</span>&nbsp;<span>{<br></span><span>3</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>double</span><span>&nbsp;keyVal;<br></span><span>4</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>struct</span><span>&nbsp;_list_node&nbsp;</span><span>*</span><span>next;<br></span><span>5</span>&nbsp;<span>}ListNode;</span></div>
Q1 <span>单链表的反序</span><br>
<div><img id=Code_Closed_Image_040202 onclick="this.style.display='none'; document.getElementById('Code_Closed_Text_040202').style.display='none'; document.getElementById('Code_Open_Image_040202').style.display='inline'; document.getElementById('Code_Open_Text_040202').style.display='inline';" align=top src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" width=11 height=16><img id=Code_Open_Image_040202 onclick="this.style.display='none'; document.getElementById('Code_Open_Text_040202').style.display='none'; getElementById('Code_Closed_Image_040202').style.display='inline'; getElementById('Code_Closed_Text_040202').style.display='inline';" align=top src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" width=11 height=16><span id=Code_Closed_Text_040202>Code</span><span id=Code_Open_Text_040202><br><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span>&nbsp;1</span>&nbsp;<span>ListNode</span><span>*</span><span>&nbsp;reverseList(ListNode</span><span>*</span><span>&nbsp;head)<br></span><span>&nbsp;2</span>&nbsp;<span>{<br></span><span>&nbsp;3</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;ListNode&nbsp;</span><span>*</span><span>p1,&nbsp;</span><span>*</span><span>p2&nbsp;,&nbsp;</span><span>*</span><span>p3;<br></span><span>&nbsp;4</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>//</span><span>链表为空，或是单结点链表直接返回头结点</span><span><br></span><span>&nbsp;5</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>if</span><span>&nbsp;(head&nbsp;</span><span>==</span><span>&nbsp;NULL&nbsp;</span><span>||</span><span>&nbsp;head</span><span>-&gt;</span><span>next&nbsp;</span><span>==</span><span>&nbsp;NULL)<br></span><span>&nbsp;6</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span>&nbsp;7</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>return</span><span>&nbsp;head;<br></span><span>&nbsp;8</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span>&nbsp;9</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;p1&nbsp;</span><span>=</span><span>&nbsp;head;<br></span><span>10</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;p2&nbsp;</span><span>=</span><span>&nbsp;head</span><span>-&gt;</span><span>next;<br></span><span>11</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>while</span><span>&nbsp;(p2&nbsp;</span><span>!=</span><span>&nbsp;NULL)<br></span><span>12</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span>13</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p3&nbsp;</span><span>=</span><span>&nbsp;p2</span><span>-&gt;</span><span>next;<br></span><span>14</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p2</span><span>-&gt;</span><span>next&nbsp;</span><span>=</span><span>&nbsp;p1;<br></span><span>15</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p1&nbsp;</span><span>=</span><span>&nbsp;p2;<br></span><span>16</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p2&nbsp;</span><span>=</span><span>&nbsp;p3;<br></span><span>17</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span>18</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;head</span><span>-&gt;</span><span>next&nbsp;</span><span>=</span><span>&nbsp;NULL;<br></span><span>19</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;head&nbsp;</span><span>=</span><span>&nbsp;p1;<br></span><span>20</span>&nbsp;<span><br></span><span>21</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>return</span><span>&nbsp;head;<br></span><span>22</span>&nbsp;<span>}</span></span></div>
<span><span>Q2 </span><span>找出链表的中间元素<br></span>
<div><img id=Code_Closed_Image_040259 onclick="this.style.display='none'; document.getElementById('Code_Closed_Text_040259').style.display='none'; document.getElementById('Code_Open_Image_040259').style.display='inline'; document.getElementById('Code_Open_Text_040259').style.display='inline';" align=top src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" width=11 height=16><img id=Code_Open_Image_040259 onclick="this.style.display='none'; document.getElementById('Code_Open_Text_040259').style.display='none'; getElementById('Code_Closed_Image_040259').style.display='inline'; getElementById('Code_Closed_Text_040259').style.display='inline';" align=top src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" width=11 height=16><span id=Code_Closed_Text_040259>Code</span><span id=Code_Open_Text_040259><br><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span>&nbsp;1</span>&nbsp;<span>ListNode</span><span>*</span><span>&nbsp;find_midlist(ListNode</span><span>*</span><span>&nbsp;head)<br></span><span>&nbsp;2</span>&nbsp;<span>{<br></span><span>&nbsp;3</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;ListNode&nbsp;</span><span>*</span><span>p1,&nbsp;</span><span>*</span><span>p2;<br></span><span>&nbsp;4</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span>&nbsp;5</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>if</span><span>&nbsp;(head&nbsp;</span><span>==</span><span>&nbsp;NULL&nbsp;</span><span>||</span><span>&nbsp;head</span><span>-&gt;</span><span>next&nbsp;</span><span>==</span><span>&nbsp;NULL)<br></span><span>&nbsp;6</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span>&nbsp;7</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>return</span><span>&nbsp;head;<br></span><span>&nbsp;8</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span>&nbsp;9</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;p1&nbsp;</span><span>=</span><span>&nbsp;p2&nbsp;</span><span>=</span><span>&nbsp;head;<br></span><span>10</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>while</span><span>&nbsp;(</span><span>1</span><span>)<br></span><span>11</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span>12</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>if</span><span>&nbsp;(p2</span><span>-&gt;</span><span>next&nbsp;</span><span>!=</span><span>&nbsp;NULL&nbsp;</span><span>&amp;&amp;</span><span>&nbsp;p2</span><span>-&gt;</span><span>next</span><span>-&gt;</span><span>next&nbsp;</span><span>!=</span><span>&nbsp;NULL)<br></span><span>13</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span>14</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p2&nbsp;</span><span>=</span><span>&nbsp;p2</span><span>-&gt;</span><span>next</span><span>-&gt;</span><span>next;<br></span><span>15</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p1&nbsp;</span><span>=</span><span>&nbsp;p1</span><span>-&gt;</span><span>next;<br></span><span>16</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span>17</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>else</span><span><br></span><span>18</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span>19</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>break</span><span>;<br></span><span>20</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span>21</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span>22</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>return</span><span>&nbsp;p1;<br></span><span>23</span>&nbsp;<span>}</span></span></div>
<br></span>
<p><span>思路分析：</span></p>
<p>&nbsp;<span>单</span><span>链表的一个比较大的特点用一句广告语来说就是&#8220;不走回头路&#8221;，不能实现随机存取（random access）。如果我们想要找一个数组a的中间元素，直接a[len/2]就可以了，但是链表不行，因为只有a[len/2 - 1] 知道a[len/2]在哪儿，其他人不知道。因此，如果按照数组的做法依样画葫芦，要找到链表的中点，我们需要做两步（1）知道链表有多长（2）从头结点开始顺序遍历到链表长度的一半的位置。这就需要1.5n（n为链表的长度）的时间复杂度了。有没有更好的办法呢？有的。想法很简单：两个人赛跑，如果A的速度是B的两倍的话，当A到终点的时候，B应该刚到中点。这只需要遍历一遍链表就行了，还不用计算链表的长度。</span></p>
<p>&nbsp;<span>上面的代码就体现了这个想法。</span></p>
<span>Q3&nbsp;</span><span>链表排序<br></span>
<div><img id=Code_Closed_Image_040420 onclick="this.style.display='none'; document.getElementById('Code_Closed_Text_040420').style.display='none'; document.getElementById('Code_Open_Image_040420').style.display='inline'; document.getElementById('Code_Open_Text_040420').style.display='inline';" align=top src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" width=11 height=16><img id=Code_Open_Image_040420 onclick="this.style.display='none'; document.getElementById('Code_Open_Text_040420').style.display='none'; getElementById('Code_Closed_Image_040420').style.display='inline'; getElementById('Code_Closed_Text_040420').style.display='inline';" align=top src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" width=11 height=16><span id=Code_Closed_Text_040420>Code</span><span id=Code_Open_Text_040420><br><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span>&nbsp;1</span>&nbsp;<span>double</span><span>&nbsp;cmp(ListNode&nbsp;</span><span>*</span><span>p&nbsp;,ListNode&nbsp;</span><span>*</span><span>q)<br></span><span>&nbsp;2</span>&nbsp;<span>{</span><span>return</span><span>&nbsp;(p</span><span>-&gt;</span><span>keyVal&nbsp;</span><span>-</span><span>&nbsp;q</span><span>-&gt;</span><span>keyVal);}<br></span><span>&nbsp;3</span>&nbsp;<span><br></span><span>&nbsp;4</span>&nbsp;<span>ListNode</span><span>*</span><span>&nbsp;mergeSortList(ListNode&nbsp;</span><span>*</span><span>head)<br></span><span>&nbsp;5</span>&nbsp;<span>{<br></span><span>&nbsp;6</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;ListNode&nbsp;</span><span>*</span><span>p,&nbsp;</span><span>*</span><span>q,&nbsp;</span><span>*</span><span>tail,&nbsp;</span><span>*</span><span>e;<br></span><span>&nbsp;7</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>int</span><span>&nbsp;nstep&nbsp;</span><span>=</span>&nbsp;<span>1</span><span>;<br></span><span>&nbsp;8</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>int</span><span>&nbsp;nmerges&nbsp;</span><span>=</span>&nbsp;<span>0</span><span>;<br></span><span>&nbsp;9</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>int</span><span>&nbsp;i;<br></span><span>10</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>int</span><span>&nbsp;psize,&nbsp;qsize;<br></span><span>11</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>if</span><span>&nbsp;(head&nbsp;</span><span>==</span><span>&nbsp;NULL&nbsp;</span><span>||</span><span>&nbsp;head</span><span>-&gt;</span><span>next&nbsp;</span><span>==</span><span>&nbsp;NULL)<br></span><span>12</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;{</span><span>return</span><span>&nbsp;head;}<br></span><span>13</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>while</span><span>&nbsp;(</span><span>1</span><span>)<br></span><span>14</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;p&nbsp;</span><span>=</span><span>&nbsp;head;<br></span><span>15</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tail&nbsp;</span><span>=</span><span>&nbsp;NULL;<br></span><span>16</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nmerges&nbsp;</span><span>=</span>&nbsp;<span>0</span><span>;<br></span><span>17</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>while</span><span>&nbsp;(p)<br></span><span>18</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;nmerges</span><span>++</span><span>;&nbsp;&nbsp;q&nbsp;</span><span>=</span><span>&nbsp;p;&nbsp;&nbsp;psize&nbsp;</span><span>=</span>&nbsp;<span>0</span><span>;<br></span><span>19</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>for</span><span>&nbsp;(i&nbsp;</span><span>=</span>&nbsp;<span>0</span><span>;&nbsp;i&nbsp;</span><span>&lt;</span><span>&nbsp;nstep;&nbsp;i</span><span>++</span><span>){<br></span><span>20</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;psize</span><span>++</span><span>;<br></span><span>21</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q&nbsp;</span><span>=</span><span>&nbsp;q</span><span>-&gt;</span><span>next;<br></span><span>22</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>if</span><span>&nbsp;(q&nbsp;</span><span>==</span><span>&nbsp;NULL)</span><span>break</span><span>;<br></span><span>23</span>&nbsp;<span>}<br></span><span>24</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;qsize&nbsp;</span><span>=</span><span>&nbsp;nstep;<br></span><span>25</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>while</span><span>&nbsp;(psize&nbsp;</span><span>&gt;</span><span>0</span>&nbsp;<span>||</span><span>&nbsp;(qsize&nbsp;</span><span>&gt;</span><span>0</span>&nbsp;<span>&amp;&amp;</span><span>&nbsp;q))<br></span><span>26</span>&nbsp;<span>{<br></span><span>27</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>if</span><span>&nbsp;(psize&nbsp;</span><span>==</span>&nbsp;<span>0</span><span>&nbsp;){e&nbsp;</span><span>=</span><span>&nbsp;q;&nbsp;q&nbsp;</span><span>=</span><span>&nbsp;q</span><span>-&gt;</span><span>next;&nbsp;qsize</span><span>--</span><span>;}<br></span><span>28</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;elseif&nbsp;(q&nbsp;</span><span>==</span><span>&nbsp;NULL&nbsp;</span><span>||</span><span>&nbsp;qsize&nbsp;</span><span>==</span>&nbsp;<span>0</span><span>){e&nbsp;</span><span>=</span><span>&nbsp;p;&nbsp;p&nbsp;</span><span>=</span><span>&nbsp;p</span><span>-&gt;</span><span>next;&nbsp;psize</span><span>--</span><span>;}<br></span><span>29</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;elseif&nbsp;(cmp(p,q)&nbsp;</span><span>&lt;=</span>&nbsp;<span>0</span><span>){e&nbsp;</span><span>=</span><span>&nbsp;p;&nbsp;p&nbsp;</span><span>=</span><span>&nbsp;p</span><span>-&gt;</span><span>next;&nbsp;psize</span><span>--</span><span>;}<br></span><span>30</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>else</span><span>{e&nbsp;</span><span>=</span><span>&nbsp;q;&nbsp;q&nbsp;</span><span>=</span><span>&nbsp;q</span><span>-&gt;</span><span>next;&nbsp;qsize</span><span>--</span><span>;}<br></span><span>31</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>if</span><span>&nbsp;(tail&nbsp;</span><span>!=</span><span>&nbsp;NULL){tail</span><span>-&gt;</span><span>next&nbsp;</span><span>=</span><span>&nbsp;e;}<br></span><span>32</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>else</span><span>{head&nbsp;</span><span>=</span><span>&nbsp;e;}<br></span><span>33</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tail&nbsp;</span><span>=</span><span>&nbsp;e;<br></span><span>34</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span>35</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;</span><span>=</span><span>&nbsp;q;<br></span><span>36</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span>37</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tail</span><span>-&gt;</span><span>next&nbsp;</span><span>=</span><span>&nbsp;NULL;<br></span><span>38</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>if</span><span>&nbsp;(nmerges&nbsp;</span><span>&lt;=</span>&nbsp;<span>1</span><span>){</span><span>return</span><span>&nbsp;head;}<br></span><span>39</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>else</span><span>{nstep&nbsp;</span><span>&lt;&lt;=</span>&nbsp;<span>1</span><span>;}<br></span><span>40</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span>41</span>&nbsp;<span>}</span></span></div>
<br>
<p><span>思路分析：</span></p>
<p><span>&nbsp;</span><span>&nbsp;</span><span>链表排序最好使用归并排序算法。堆排序、快速排序这些在数组排序时性能非常好的算法，在链表只能&#8220;顺序访问&#8221;的魔咒下无法施展能力；但是归并排序却如鱼得水，非但保持了它O(nlogn)</span><span>的时间复杂度，而且它在数组排序中广受诟病的空间复杂度在链表排序中也从</span><span><span>O(n)</span></span><span>降到了</span><span><span>O(1)</span></span><span>。真是好得不得了啊，哈哈。以上程序是递推法的程序，另外值得一说的是看看那个时间复杂度，是不是有点眼熟？对！这就是分治法的时间复杂度，归并排序又是</span><span>divide and conquer</span><span>。</span></p>
<span>Q4&nbsp;</span><span>判断一个单链表是否有环<br></span>
<div><img id=Code_Closed_Image_040508 onclick="this.style.display='none'; document.getElementById('Code_Closed_Text_040508').style.display='none'; document.getElementById('Code_Open_Image_040508').style.display='inline'; document.getElementById('Code_Open_Text_040508').style.display='inline';" align=top src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" width=11 height=16><img id=Code_Open_Image_040508 onclick="this.style.display='none'; document.getElementById('Code_Open_Text_040508').style.display='none'; getElementById('Code_Closed_Image_040508').style.display='inline'; getElementById('Code_Closed_Text_040508').style.display='inline';" align=top src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" width=11 height=16><span id=Code_Closed_Text_040508>Code</span><span id=Code_Open_Text_040508><br><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span>&nbsp;1</span>&nbsp;<span>int</span><span>&nbsp;is_looplist&nbsp;(ListNode&nbsp;</span><span>*</span><span>head)<br></span><span>&nbsp;2</span>&nbsp;<span>{<br></span><span>&nbsp;3</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;ListNode&nbsp;</span><span>*</span><span>p1,&nbsp;</span><span>*</span><span>p2;<br></span><span>&nbsp;4</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;p1&nbsp;</span><span>=</span><span>&nbsp;p2&nbsp;</span><span>=</span><span>&nbsp;head;<br></span><span>&nbsp;5</span>&nbsp;<span><br></span><span>&nbsp;6</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>if</span><span>&nbsp;(head&nbsp;</span><span>==</span><span>&nbsp;NULL&nbsp;</span><span>||</span><span>&nbsp;head</span><span>-&gt;</span><span>next&nbsp;</span><span>==</span><span>&nbsp;NULL)<br></span><span>&nbsp;7</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span>&nbsp;8</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>return</span>&nbsp;<span>0</span><span>;<br></span><span>&nbsp;9</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span>10</span>&nbsp;<span><br></span><span>11</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>while</span><span>&nbsp;(p2</span><span>-&gt;</span><span>next&nbsp;</span><span>!=</span><span>&nbsp;NULL&nbsp;</span><span>&amp;&amp;</span><span>&nbsp;p2</span><span>-&gt;</span><span>next</span><span>-&gt;</span><span>next&nbsp;</span><span>!=</span><span>&nbsp;NULL)<br></span><span>12</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span>13</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p1&nbsp;</span><span>=</span><span>&nbsp;p1</span><span>-&gt;</span><span>next;<br></span><span>14</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p2&nbsp;</span><span>=</span><span>&nbsp;p2</span><span>-&gt;</span><span>next</span><span>-&gt;</span><span>next;<br></span><span>15</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>if</span><span>&nbsp;(p1&nbsp;</span><span>==</span><span>&nbsp;p2)<br></span><span>16</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span>17</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>return</span>&nbsp;<span>1</span><span>;<br></span><span>18</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span>19</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span>20</span>&nbsp;<span><br></span><span>21</span>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>return</span>&nbsp;<span>0</span><span>;<br></span><span>22</span>&nbsp;<span><br></span><span>23</span>&nbsp;<span>}</span></span></div>
<br>
<p><span>思路分析：</span></p>
<p><span>&nbsp;</span><span>&nbsp;</span><span>这道题是《<span>C</span>专家编程》中的题了。其实算法也有很多，比如说：我觉得进行对访问过的结点进行标记这个想法也不错，而且在树遍历等场合我们也经常使用。但是在不允许做标记的场合就无法使用了。在种种限制的条件下，就有了上面的这种算法，其实思想很简单：就像两个人在操场上跑步一样，只要有个人的速度比另一个人的速度快一点，他们肯定会有相遇的时候的。不过带环链表与操场又不一样，带环链表的状态是离散的，所以选择走得快的要比走得慢的快多少很重要。比如说这里，如果一个指针一次走三步，一个指针一次走一步的话，很有可能它们虽然在一个环中但是永远遇不到，这要取决于环的大小以及两个指针初始位置相差多少了。呵呵。你能看出两个指针的速度应该满足什么关系才能在有环的情况下相遇吗？如果你知道，不妨跟我讨论一下，呵呵。</span></p>
<img src ="http://www.cppblog.com/koson/aggbug/113142.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/koson/" target="_blank">koson</a> 2010-04-21 15:50 <a href="http://www.cppblog.com/koson/archive/2010/04/21/113142.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>POJ 1094 拓扑排序</title><link>http://www.cppblog.com/koson/archive/2010/04/20/113074.html</link><dc:creator>koson</dc:creator><author>koson</author><pubDate>Tue, 20 Apr 2010 07:42:00 GMT</pubDate><guid>http://www.cppblog.com/koson/archive/2010/04/20/113074.html</guid><wfw:comment>http://www.cppblog.com/koson/comments/113074.html</wfw:comment><comments>http://www.cppblog.com/koson/archive/2010/04/20/113074.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/koson/comments/commentRss/113074.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/koson/services/trackbacks/113074.html</trackback:ping><description><![CDATA[<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">使用深搜，根据每个结点的结束访问时间的降序对结点进行拓扑排序，如果在某个结点的扩展过程中发现反向边，则出现了矛盾；否则对所得到的结点序列，进行一次遍历，对于相邻的结点检测是否存在连接边（存在则表示它们的顺序已经可以确定），如果所有的相邻结点都可确定顺序，则这个序列是完全有序的，对于后面的输入可以忽略；如果处理完所有的输入还不能得到完全有序序列，则输出序列顺序不能确定。<br>题意实际上暗示了对每一次输入都要做处理，如果对于某一次输入已经能确定序列矛盾或者序列完全有序，则可以忽略后面的输入。<br><br><br>&nbsp;1</span>&nbsp;<span style="color: #000000;">#include</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">stdio.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;">#include</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">string</span><span style="color: #000000;">.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;n,m;<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;e[</span><span style="color: #000000;">27</span><span style="color: #000000;">][</span><span style="color: #000000;">27</span><span style="color: #000000;">];<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">in</span><span style="color: #000000;">[</span><span style="color: #000000;">4</span><span style="color: #000000;">];<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;temp[</span><span style="color: #000000;">27</span><span style="color: #000000;">];<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;cur;<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;incons;<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;color[</span><span style="color: #000000;">27</span><span style="color: #000000;">];<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;dfs(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;k)<br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;color[k]</span><span style="color: #000000;">=</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i;<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">(i</span><span style="color: #000000;">=</span><span style="color: #000000;">1</span><span style="color: #000000;">;i</span><span style="color: #000000;">&lt;=</span><span style="color: #000000;">n;</span><span style="color: #000000;">++</span><span style="color: #000000;">i)<br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(e[k][i]</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">color[i]</span><span style="color: #000000;">==</span><span style="color: #000000;">0</span><span style="color: #000000;">)&nbsp;dfs(i);<br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(e[k][i]</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">color[i]</span><span style="color: #000000;">==</span><span style="color: #000000;">1</span><span style="color: #000000;">)&nbsp;incons</span><span style="color: #000000;">=</span><span style="color: #000000;">1</span><span style="color: #000000;">;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">reverse&nbsp;edge&nbsp;exist,&nbsp;inconsistency&nbsp;found</span><span style="color: #008000;"><br></span><span style="color: #008080;">18</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;color[k]</span><span style="color: #000000;">=</span><span style="color: #000000;">2</span><span style="color: #000000;">;<br></span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;temp[cur</span><span style="color: #000000;">++</span><span style="color: #000000;">]</span><span style="color: #000000;">=</span><span style="color: #000000;">k</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">+</span><span style="color: #000000;">'</span><span style="color: #000000;">A</span><span style="color: #000000;">'</span><span style="color: #000000;">;<br></span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;main()<br></span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i,j,found;<br></span><span style="color: #008080;">25</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">(scanf(</span><span style="color: #000000;">"</span><span style="color: #000000;">%d%d</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">n,</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">m)</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">n</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">m)<br></span><span style="color: #008080;">26</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">27</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memset(e,</span><span style="color: #000000;">0</span><span style="color: #000000;">,</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(e));<br></span><span style="color: #008080;">28</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;found</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">29</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;incons</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">30</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">(i</span><span style="color: #000000;">=</span><span style="color: #000000;">1</span><span style="color: #000000;">;i</span><span style="color: #000000;">&lt;=</span><span style="color: #000000;">m;</span><span style="color: #000000;">++</span><span style="color: #000000;">i)<br></span><span style="color: #008080;">31</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">32</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scanf(</span><span style="color: #000000;">"</span><span style="color: #000000;">%s</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #0000ff;">in</span><span style="color: #000000;">);<br></span><span style="color: #008080;">33</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e[</span><span style="color: #0000ff;">in</span><span style="color: #000000;">[</span><span style="color: #000000;">0</span><span style="color: #000000;">]</span><span style="color: #000000;">-</span><span style="color: #000000;">'</span><span style="color: #000000;">A</span><span style="color: #000000;">'</span><span style="color: #000000;">+</span><span style="color: #000000;">1</span><span style="color: #000000;">][</span><span style="color: #0000ff;">in</span><span style="color: #000000;">[</span><span style="color: #000000;">2</span><span style="color: #000000;">]</span><span style="color: #000000;">-</span><span style="color: #000000;">'</span><span style="color: #000000;">A</span><span style="color: #000000;">'</span><span style="color: #000000;">+</span><span style="color: #000000;">1</span><span style="color: #000000;">]</span><span style="color: #000000;">=</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br></span><span style="color: #008080;">34</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(</span><span style="color: #000000;">!</span><span style="color: #000000;">found</span><span style="color: #000000;">&amp;&amp;!</span><span style="color: #000000;">incons)<br></span><span style="color: #008080;">35</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">36</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cur</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">37</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memset(color,</span><span style="color: #000000;">0</span><span style="color: #000000;">,</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(color));<br></span><span style="color: #008080;">38</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">(j</span><span style="color: #000000;">=</span><span style="color: #000000;">1</span><span style="color: #000000;">;j</span><span style="color: #000000;">&lt;=</span><span style="color: #000000;">n;</span><span style="color: #000000;">++</span><span style="color: #000000;">j)<br></span><span style="color: #008080;">39</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(color[j]</span><span style="color: #000000;">==</span><span style="color: #000000;">0</span><span style="color: #000000;">)&nbsp;dfs(j);<br></span><span style="color: #008080;">40</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp[cur]</span><span style="color: #000000;">=</span><span style="color: #000000;">'</span><span style="color: #000000;">\0</span><span style="color: #000000;">'</span><span style="color: #000000;">;<br></span><span style="color: #008080;">41</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(incons</span><span style="color: #000000;">==</span><span style="color: #000000;">1</span><span style="color: #000000;">)&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">inconsistency&nbsp;found</span><span style="color: #008000;"><br></span><span style="color: #008080;">42</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;incons</span><span style="color: #000000;">=</span><span style="color: #000000;">i;<br></span><span style="color: #008080;">43</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{<br></span><span style="color: #008080;">44</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;bb</span><span style="color: #000000;">=</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br></span><span style="color: #008080;">45</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">(j</span><span style="color: #000000;">=</span><span style="color: #000000;">cur</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">;j</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">0</span><span style="color: #000000;">;</span><span style="color: #000000;">--</span><span style="color: #000000;">j)&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">check&nbsp;if&nbsp;the&nbsp;sort&nbsp;of&nbsp;sequence&nbsp;can&nbsp;be&nbsp;confirmed</span><span style="color: #008000;"><br></span><span style="color: #008080;">46</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(</span><span style="color: #000000;">!</span><span style="color: #000000;">e[temp[j]</span><span style="color: #000000;">-</span><span style="color: #000000;">'</span><span style="color: #000000;">A</span><span style="color: #000000;">'</span><span style="color: #000000;">+</span><span style="color: #000000;">1</span><span style="color: #000000;">][temp[j</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">]</span><span style="color: #000000;">-</span><span style="color: #000000;">'</span><span style="color: #000000;">A</span><span style="color: #000000;">'</span><span style="color: #000000;">+</span><span style="color: #000000;">1</span><span style="color: #000000;">])&nbsp;{bb</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;}<br></span><span style="color: #008080;">47</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(bb)&nbsp;found</span><span style="color: #000000;">=</span><span style="color: #000000;">i;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;sorted&nbsp;sequence&nbsp;determined</span><span style="color: #008000;"><br></span><span style="color: #008080;">48</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">49</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">50</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">51</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;tt;<br></span><span style="color: #008080;">52</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">(i</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">,j</span><span style="color: #000000;">=</span><span style="color: #000000;">cur</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">;i</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">j;i</span><span style="color: #000000;">++</span><span style="color: #000000;">,j</span><span style="color: #000000;">--</span><span style="color: #000000;">)&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">reverse&nbsp;the&nbsp;sorted&nbsp;sequence</span><span style="color: #008000;"><br></span><span style="color: #008080;">53</span>&nbsp;<span style="color: #008000;"></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">54</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tt</span><span style="color: #000000;">=</span><span style="color: #000000;">temp[i];<br></span><span style="color: #008080;">55</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp[i]</span><span style="color: #000000;">=</span><span style="color: #000000;">temp[j];<br></span><span style="color: #008080;">56</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp[j]</span><span style="color: #000000;">=</span><span style="color: #000000;">tt;<br></span><span style="color: #008080;">57</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">58</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(incons)&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">Inconsistency&nbsp;found&nbsp;after&nbsp;%d&nbsp;relations.\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,incons);<br></span><span style="color: #008080;">59</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(found)&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">Sorted&nbsp;sequence&nbsp;determined&nbsp;after&nbsp;%d&nbsp;relations:&nbsp;%s.\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,found,temp);<br></span><span style="color: #008080;">60</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">Sorted&nbsp;sequence&nbsp;cannot&nbsp;be&nbsp;determined.\n</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br></span><span style="color: #008080;">61</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">62</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br></span><span style="color: #008080;">63</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">64</span>&nbsp;<span style="color: #000000;"></span></div><img src ="http://www.cppblog.com/koson/aggbug/113074.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/koson/" target="_blank">koson</a> 2010-04-20 15:42 <a href="http://www.cppblog.com/koson/archive/2010/04/20/113074.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>POJ 1724 搜索＋优化</title><link>http://www.cppblog.com/koson/archive/2010/04/19/112988.html</link><dc:creator>koson</dc:creator><author>koson</author><pubDate>Mon, 19 Apr 2010 07:05:00 GMT</pubDate><guid>http://www.cppblog.com/koson/archive/2010/04/19/112988.html</guid><wfw:comment>http://www.cppblog.com/koson/comments/112988.html</wfw:comment><comments>http://www.cppblog.com/koson/archive/2010/04/19/112988.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/koson/comments/commentRss/112988.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/koson/services/trackbacks/112988.html</trackback:ping><description><![CDATA[用深度优先搜索，由于每对顶点之间可能会有不同路径长度或费用值，所以采用邻接表来表示图。搜索过程中，剪掉那些当前路径长度大于前面已经计算得出的最小值或者当前花费值大于所有值的分支。<br><img src ="http://www.cppblog.com/koson/aggbug/112988.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/koson/" target="_blank">koson</a> 2010-04-19 15:05 <a href="http://www.cppblog.com/koson/archive/2010/04/19/112988.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>poj 1988　并查集的应用</title><link>http://www.cppblog.com/koson/archive/2010/04/08/111946.html</link><dc:creator>koson</dc:creator><author>koson</author><pubDate>Thu, 08 Apr 2010 04:27:00 GMT</pubDate><guid>http://www.cppblog.com/koson/archive/2010/04/08/111946.html</guid><wfw:comment>http://www.cppblog.com/koson/comments/111946.html</wfw:comment><comments>http://www.cppblog.com/koson/archive/2010/04/08/111946.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/koson/comments/commentRss/111946.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/koson/services/trackbacks/111946.html</trackback:ping><description><![CDATA[　　题意是给出N个立方体，可以将立方体移动到其它立方体形成堆，然后有P个下面的操作: 1) M X Y ,将X立方体所在的堆移到Y立方体所在的堆的上面;&nbsp; 2) C X 输出在X所在的堆上,在X立方体下面的立方体个数。<br>　　使用并查集来解决这个问题。关键在于怎么存储和更新立方体的结果(即操作2的输出值)。用三个数组，p,h,t, p[i]表示i的根结点，h[i]表示i的结果，即压在i下面的立方体个数，t[i]表示i所在的堆的立方体总个数。对于每一堆立方体，根结点使用堆底的立方体，而且在这个堆所对应的集合内，通过更新，使得只有根结点的t值为这堆的总个数，h值为0(因为它在堆底)，其它的立方体的t值都为0，h值在并查集的查找步骤中进行递归更新。　　　<br>　　在并查集的查找函数的执行中，先向上找到根结点，并且保存当前结点x的父节点为temp，找到根结点后，向下依次一更新结点的h,t值。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1)若t[x]不为0,即表示x是一个堆的堆底元素，h[x]为0,其父节点是另外一堆的堆底(因为在并查集的操作中，通过将一个堆的堆底指向另一个堆的堆底来实现合并),　h[x]+=t[temp],t[temp]+=t[x],t[x]=0 ，这三个语句将x的h值加上父结点的总个数(因为是将x所在的堆放在父节点的堆),然后将父节点的t值加上x的t值(父节点的堆的总数变为两者之和），然后再将x的t值置0.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2)若t[x]为0,即表示x不是堆底，那么只要将x的h值加上父节点的h值即可。h[x]+=h[temp] 。<br>　　画个图然后稍微分析查找操作的过程就能得到上面的结果。下面是并查集的几个函数。在合并操作里面，合并完后我们再对x,y执行一次查找操作以更新对应堆的值，因为在下次合并的时候可能堆还没有来得及更新。<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;make_set()<br></span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i;<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">(i</span><span style="color: #000000;">=</span><span style="color: #000000;">1</span><span style="color: #000000;">;i</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">N;</span><span style="color: #000000;">++</span><span style="color: #000000;">i)<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p[i]</span><span style="color: #000000;">=</span><span style="color: #000000;">i;<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h[i]</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t[i]</span><span style="color: #000000;">=</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;find_set(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;x)<br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;temp;<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(x</span><span style="color: #000000;">!=</span><span style="color: #000000;">p[x])<br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp</span><span style="color: #000000;">=</span><span style="color: #000000;">p[x];<br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p[x]</span><span style="color: #000000;">=</span><span style="color: #000000;">find_set(p[x]);<br></span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(t[x]</span><span style="color: #000000;">!=</span><span style="color: #000000;">0</span><span style="color: #000000;">)<br></span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h[x]</span><span style="color: #000000;">+=</span><span style="color: #000000;">t[temp];<br></span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t[temp]</span><span style="color: #000000;">+=</span><span style="color: #000000;">t[x];<br></span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t[x]</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br></span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">25</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h[x]</span><span style="color: #000000;">+=</span><span style="color: #000000;">h[temp];<br></span><span style="color: #008080;">26</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">27</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">28</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;p[x];<br></span><span style="color: #008080;">29</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">30</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;union_set(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;x,</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;y)<br></span><span style="color: #008080;">31</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">32</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;px</span><span style="color: #000000;">=</span><span style="color: #000000;">find_set(x),py</span><span style="color: #000000;">=</span><span style="color: #000000;">find_set(y);<br></span><span style="color: #008080;">33</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;p[px]</span><span style="color: #000000;">=</span><span style="color: #000000;">py;<br></span><span style="color: #008080;">34</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;find_set(x),find_set(y);<br></span><span style="color: #008080;">35</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">36</span>&nbsp;<span style="color: #000000;"></span></div>
<br><br><img src ="http://www.cppblog.com/koson/aggbug/111946.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/koson/" target="_blank">koson</a> 2010-04-08 12:27 <a href="http://www.cppblog.com/koson/archive/2010/04/08/111946.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>二叉树前序、中序、后序三种遍历的非递归算法 </title><link>http://www.cppblog.com/koson/archive/2010/03/18/109972.html</link><dc:creator>koson</dc:creator><author>koson</author><pubDate>Thu, 18 Mar 2010 04:23:00 GMT</pubDate><guid>http://www.cppblog.com/koson/archive/2010/03/18/109972.html</guid><wfw:comment>http://www.cppblog.com/koson/comments/109972.html</wfw:comment><comments>http://www.cppblog.com/koson/archive/2010/03/18/109972.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/koson/comments/commentRss/109972.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/koson/services/trackbacks/109972.html</trackback:ping><description><![CDATA[<p><strong>一。教科书标准算法<br></strong><font size=2>1.先序遍历非递归算法<br>void PreOrderUnrec(Bitree *t)<br>{<br>&nbsp;&nbsp;&nbsp; Stack s;<br>&nbsp; &nbsp; StackInit(s);<br>&nbsp; &nbsp; Bitree *p=t;<br>&nbsp; &nbsp; <br>&nbsp; &nbsp; while (p!=NULL || !StackEmpty(s))<br>&nbsp; &nbsp; {<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;while (p!=NULL)&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; //遍历左子树<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;{<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;visite(p-&gt;data);<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;push(s,p);<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;p=p-&gt;lchild;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!StackEmpty(s))&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;//通过下一次循环中的内嵌while实现右子树遍历<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;{<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;p=pop(s);<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;p=p-&gt;rchild;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}//endif<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; <br>&nbsp; &nbsp; }//endwhile&nbsp;<br>}<br><br>2.中序遍历非递归算法<br>void InOrderUnrec(Bitree *t)<br>{<br>&nbsp;&nbsp;&nbsp; Stack s;<br>&nbsp; &nbsp; StackInit(s);<br>&nbsp; &nbsp; Bitree *p=t;<br><br>&nbsp;&nbsp;&nbsp; while (p!=NULL || !StackEmpty(s))<br>&nbsp; &nbsp; {<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;while (p!=NULL)&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; //遍历左子树<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;{<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;push(s,p);<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;p=p-&gt;lchild;<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!StackEmpty(s))<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;{<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;p=pop(s);<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;visite(p-&gt;data);&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;//访问根结点<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;p=p-&gt;rchild;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;//通过下一次循环实现右子树遍历<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}//endif&nbsp; &nbsp;<br>&nbsp; &nbsp; <br>&nbsp; &nbsp; }//endwhile<br>}<br><br>3.后序遍历非递归算法<br>typedef enum{L,R} tagtype;<br>typedef struct <br>{<br>&nbsp; &nbsp; Bitree ptr;<br>&nbsp; &nbsp; tagtype tag;<br>}stacknode;<br><br>typedef struct<br>{<br>&nbsp; &nbsp; stacknode Elem[maxsize];<br>&nbsp; &nbsp; int top;<br>}SqStack;<br><br>void PostOrderUnrec(Bitree t)<br>{<br>&nbsp; &nbsp; SqStack s;<br>&nbsp; &nbsp; stacknode x;<br>&nbsp; &nbsp; StackInit(s);<br>&nbsp; &nbsp; p=t;<br>&nbsp; &nbsp; <br>&nbsp; &nbsp; do <br>&nbsp; &nbsp; {<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;while (p!=null)&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;//遍历左子树<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;{<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;x.ptr = p; <br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;x.tag = L;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;//标记为左子树<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;push(s,x);<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;p=p-&gt;lchild;<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}<br>&nbsp; &nbsp; <br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;while (!StackEmpty(s) &amp;&amp; s.Elem[s.top].tag==R)&nbsp;&nbsp;<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;{<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;x = pop(s);<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;p = x.ptr;<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;visite(p-&gt;data);&nbsp; &nbsp;//tag为R，表示右子树访问完毕，故访问根结点&nbsp; &nbsp;&nbsp; &nbsp; <br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;if (!StackEmpty(s))<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;{<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;s.Elem[s.top].tag =R;&nbsp; &nbsp;&nbsp;&nbsp;//遍历右子树<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;p=s.Elem[s.top].ptr-&gt;rchild;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<br>&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}&nbsp; &nbsp; <br>&nbsp; &nbsp; }while (!StackEmpty(s));<br>}//PostOrderUnrec</font><font size=3> </font><span class=smalltxt><br></span><br><strong>二。前序最简洁算法<br></strong><font size=2>void PreOrderUnrec(Bitree *t)<br>{<br>&nbsp;&nbsp; Bitree *p;<br>&nbsp;&nbsp; Stack s;<br>&nbsp;&nbsp; s.push(t);</font></p>
<p><font size=2>&nbsp;&nbsp; while (!s.IsEmpty())<br>&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.pop(p);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; visit(p-&gt;data);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (p-&gt;rchild != NULL) s.push(p-&gt;rchild);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (p-&gt;lchild != NULL) s.push(p-&gt;lchild);<br>&nbsp;&nbsp; }<br>}</font><br><br><strong>三。后序算法之二</strong><br><font size=2>void BT_PostOrderNoRec(pTreeT root) <br>{ <br>stack&lt;treeT *&gt; s; <br>pTreeT pre=NULL; </p>
<p><font size=2>while ((NULL != root) || !s.empty()) <br>{ <br>if (NULL != root) <br>{ <br>s.push(root); <br>root = root-&gt;left; <br>} <br>else <br>{ <br>root = s.top(); <br>if (root-&gt;right!=NULL &amp;&amp; pre!=root-&gt;right){ <br>root=root-&gt;right; <br>} <br>else{ <br>root=pre=s.top(); <br>visit(root); <br>s.pop(); <br>root=NULL; <br>} <br>} <br>} <br>}</font></font></p>
<img src ="http://www.cppblog.com/koson/aggbug/109972.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/koson/" target="_blank">koson</a> 2010-03-18 12:23 <a href="http://www.cppblog.com/koson/archive/2010/03/18/109972.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>o(n)时间求出n个元素的第k个</title><link>http://www.cppblog.com/koson/archive/2010/03/17/109906.html</link><dc:creator>koson</dc:creator><author>koson</author><pubDate>Wed, 17 Mar 2010 08:25:00 GMT</pubDate><guid>http://www.cppblog.com/koson/archive/2010/03/17/109906.html</guid><wfw:comment>http://www.cppblog.com/koson/comments/109906.html</wfw:comment><comments>http://www.cppblog.com/koson/archive/2010/03/17/109906.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/koson/comments/commentRss/109906.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/koson/services/trackbacks/109906.html</trackback:ping><description><![CDATA[<p>利用快速排序的分组思路，假设对当前主元值t,已将数组分成三个部分，a[0,m-1]部分都小于t，a[m]等于t,a[m+1,n-1]大于等于t,此时比较m+1与k,若m+1&lt;k，可知第k个元素在右半部分，所以将分组区间的左下标改为m+1,同理，若m+1&gt;k，则将分组区间的右下标改为m-1,若是m+1==k,则表示找到了第k个元素，返回a[m]。可知这个算法的时间复杂度为O(cn)，其中c为某个很小的常数。实现时，依赖于分组的方法，有单向分级与双向分组，用随机生成的百万个数据进行测试，结果单向分组的时间为双向分组的两倍。<br>代码如下：<br>#include&lt;stdio.h&gt;<br>#include&lt;time.h&gt;<br>#define MAX 1000001<br>int n,k;<br>int h[MAX];<br>int search1()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int l,r,i,m,t,temp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(l=0,r=n-1;;)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t=h[l];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m=l;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i=l+1;i&lt;=r;++i)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(h[i]&lt;t)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp=h[i];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; h[i]=h[++m];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; h[m]=temp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; h[l]=h[m];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; h[m]=t;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(m+1&lt;k) l=m+1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if(m+1&gt;k) r=m-1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return h[m];<br>}</p>
<p>int search()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int l,r,i,j,t,temp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(l=0,r=n-1;;)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t=h[l];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i=l,j=r+1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(1)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i++;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }while(i&lt;=r&amp;&amp;h[i]&lt;t);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; j--;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }while(j&gt;=l+1&amp;&amp;h[j]&gt;=t);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(i&gt;j)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp=h[i];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; h[i]=h[j];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; h[j]=temp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; h[l]=h[j];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; h[j]=t;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(j+1&lt;k)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; l=j+1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if(j+1&gt;k)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r=j-1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return h[j];<br>}</p>
<p>int main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf("%d%d",&amp;n,&amp;k);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i,j;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i=0;i&lt;n;++i)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf("%d",&amp;h[i]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; time_t start,end;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; start=clock();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%d\n",search());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end=clock();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%f\n",((end-start)*1.0)/CLOCKS_PER_SEC);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>}<br></p>
<img src ="http://www.cppblog.com/koson/aggbug/109906.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/koson/" target="_blank">koson</a> 2010-03-17 16:25 <a href="http://www.cppblog.com/koson/archive/2010/03/17/109906.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>大数据量，海量数据 处理方法总结(转）</title><link>http://www.cppblog.com/koson/archive/2010/03/15/109734.html</link><dc:creator>koson</dc:creator><author>koson</author><pubDate>Mon, 15 Mar 2010 06:40:00 GMT</pubDate><guid>http://www.cppblog.com/koson/archive/2010/03/15/109734.html</guid><wfw:comment>http://www.cppblog.com/koson/comments/109734.html</wfw:comment><comments>http://www.cppblog.com/koson/archive/2010/03/15/109734.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/koson/comments/commentRss/109734.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/koson/services/trackbacks/109734.html</trackback:ping><description><![CDATA[<p><span style="FONT-SIZE: large"><font color=#008000><strong>1.Bloom filter</strong></font></span> </p>
<div></div>
<div><strong>适用范围</strong>：可以用来实现数据字典，进行数据的判重，或者集合求交集</div>
<div></div>
<div><strong>基本原理及要点：</strong></div>
<div>对 于原理来说很简单，位数组+k个独立hash函数。将hash函数对应的值的位数组置1，查找时如果发现所有hash函数对应位都是1说明存在，很明显这 个过程并不保证查找的结果是100%正确的。同时也不支持删除一个已经插入的关键字，因为该关键字对应的位会牵动到其他的关键字。所以一个简单的改进就是 counting Bloom filter，用一个counter数组代替位数组，就可以支持删除了。<br><br></div>
<div></div>
<div>还 有一个比较重要的问题，如何根据输入元素个数n，确定位数组m的大小及hash函数个数。当hash函数个数k=(ln2)*(m/n)时错误率最小。在 错误率不大于E的情况下，m至少要等于n*lg(1/E)才能表示任意n个元素的集合。但m还应该更大些，因为还要保证bit数组里至少一半为0，则m应 该&gt;=nlg(1/E)*lge 大概就是nlg(1/E)1.44倍(lg表示以2为底的对数)。</div>
<div></div>
<div>举个例子我们假设错误率为0.01，则此时m应大概是n的13倍。这样k大概是8个。</div>
<div></div>
<div>注意这里m与n的单位不同，m是bit为单位，而n则是以元素个数为单位(准确的说是不同元素的个数)。通常单个元素的长度都是有很多bit的。所以使用bloom filter内存上通常都是节省的。</div>
<div></div>
<div><strong>扩展：</strong></div>
<div>Bloom filter将集合中的元素映射到位数组中，用k（k为哈希函数个数）个映射位是否全1表示元素在不在这个集合中。Counting bloom filter（CBF）将位数组中的每一位扩展为一个counter，从而支持了元素的删除操作。Spectral Bloom Filter（SBF）将其与集合元素的出现次数关联。SBF采用counter中的最小值来近似表示元素的出现频率。</div>
<div></div>
<div><strong>问题实例：</strong>给你A,B两个文件，各存放50亿条URL，每条URL占用64字节，内存限制是4G，让你找出A,B文件共同的URL。如果是三个乃至n个文件呢？</div>
<div></div>
<div>根 据这个问题我们来计算下内存的占用，4G=2^32大概是40亿*8大概是340亿，n=50亿，如果按出错率0.01算需要的大概是650亿个bit。 现在可用的是340亿，相差并不多，这样可能会使出错率上升些。另外如果这些urlip是一一对应的，就可以转换成ip，则大大简单了。</div>
<div></div>
<div><strong><font color=#008000><span style="FONT-SIZE: large">2.Hashing</span></font></strong></div>
<div></div>
<div><strong>适用范围：</strong>快速查找，删除的基本数据结构，通常需要总数据量可以放入内存</div>
<div></div>
<div><strong>基本原理及要点：</strong></div>
<div>hash函数选择，针对字符串，整数，排列，具体相应的hash方法。</div>
<div>碰撞处理，一种是open hashing，也称为拉链法；另一种就是closed hashing，也称开地址法，opened addressing。</div>
<div></div>
<div><strong>扩展：</strong></div>
<div>d-left hashing中的d是多个的意思，我们先简化这个问题，看一看2-left hashing。2-left hashing指的是将一个哈希表分成长度相等的两半，分别叫做T1和T2，给T1和T2分别配备一个哈希函数，h1和h2。在存储一个新的key时，同 时用两个哈希函数进行计算，得出两个地址h1[key]和h2[key]。这时需要检查T1中的h1[key]位置和T2中的h2[key]位置，哪一个 位置已经存储的（有碰撞的）key比较多，然后将新key存储在负载少的位置。如果两边一样多，比如两个位置都为空或者都存储了一个key，就把新key 存储在左边的T1子表中，2-left也由此而来。在查找一个key时，必须进行两次hash，同时查找两个位置。</div>
<div></div>
<div><strong>问题实例：</strong></div>
<div>1).海量日志数据，提取出某日访问百度次数最多的那个IP。</div>
<div></div>
<div>IP的数目还是有限的，最多2^32个，所以可以考虑使用hash将ip直接存入内存，然后进行统计。</div>
<div></div>
<div><strong><span style="FONT-SIZE: large"><font color=#008000>3.bit-map</font></span></strong></div>
<div></div>
<div><strong>适用范围：</strong>可进行数据的快速查找，判重，删除，一般来说数据范围是int的10倍以下</div>
<div></div>
<div><strong>基本原理及要点</strong>：使用bit数组来表示某些元素是否存在，比如8位电话号码</div>
<div></div>
<div><strong>扩展</strong>：bloom filter可以看做是对bit-map的扩展</div>
<div></div>
<div><strong>问题实例：</strong></div>
<div></div>
<div>1)已知某个文件内包含一些电话号码，每个号码为8位数字，统计不同号码的个数。</div>
<div></div>
<div>8位最多99 999 999，大概需要99m个bit，大概10几m字节的内存即可。</div>
<div></div>
<div>2)2.5亿个整数中找出不重复的整数的个数，内存空间不足以容纳这2.5亿个整数。</div>
<div></div>
<div>将bit-map扩展一下，用2bit表示一个数即可，0表示未出现，1表示出现一次，2表示出现2次及以上。或者我们不用2bit来进行表示，我们用两个bit-map即可模拟实现这个2bit-map。</div>
<div></div>
<div><strong><span style="FONT-SIZE: large"><font color=#008000>4.堆</font></span></strong></div>
<div></div>
<div><strong>适用范围</strong>：海量数据前n大，并且n比较小，堆可以放入内存</div>
<div></div>
<div><strong>基本原理及要点</strong>： 最大堆求前n小，最小堆求前n大。方法，比如求前n小，我们比较当前元素与最大堆里的最大元素，如果它小于最大元素，则应该替换那个最大元素。这样最后得 到的n个元素就是最小的n个。适合大数据量，求前n小，n的大小比较小的情况，这样可以扫描一遍即可得到所有的前n元素，效率很高。</div>
<div></div>
<div><strong>扩展：</strong>双堆，一个最大堆与一个最小堆结合，可以用来维护中位数。</div>
<div></div>
<div><strong>问题实例：</strong></div>
<div>1)100w个数中找最大的前100个数。</div>
<div></div>
<div>用一个100个元素大小的最小堆即可。</div>
<div></div>
<div><strong><span style="FONT-SIZE: large"><font color=#008000>5.双层桶划分</font></span></strong><strong><br></strong></div>
<div><strong>适用范围</strong>：第k大，中位数，不重复或重复的数字</div>
<div></div>
<div><strong>基本原理及要点</strong>：因为元素范围很大，不能利用直接寻址表，所以通过多次划分，逐步确定范围，然后最后在一个可以接受的范围内进行。可以通过多次缩小，双层只是一个例子。</div>
<div></div>
<div><strong>扩展：</strong></div>
<div></div>
<div><strong>问题实例</strong>：</div>
<div>1).2.5亿个整数中找出不重复的整数的个数，内存空间不足以容纳这2.5亿个整数。</div>
<div></div>
<div>有点像鸽巢原理，整数个数为2^32,也就是，我们可以将这2^32个数，划分为2^8个区域(比如用单个文件代表一个区域)，然后将数据分离到不同的区域，然后不同的区域在利用bitmap就可以直接解决了。也就是说只要有足够的磁盘空间，就可以很方便的解决。</div>
<div></div>
<div>2).5亿个int找它们的中位数。</div>
<div></div>
<div>这个例子比上面那个更明显。首先我们将int划分为2^16个区域，然后读取数据统计落到各个区域里的数的个数，之后我们根据统计结果就可以判断中位数落到那个区域，同时知道这个区域中的第几大数刚好是中位数。然后第二次扫描我们只统计落在这个区域中的那些数就可以了。</div>
<div></div>
<div>实 际上，如果不是int是int64，我们可以经过3次这样的划分即可降低到可以接受的程度。即可以先将int64分成2^24个区域，然后确定区域的第几 大数，在将该区域分成2^20个子区域，然后确定是子区域的第几大数，然后子区域里的数的个数只有2^20，就可以直接利用direct addr table进行统计了。</div>
<div></div>
<div><strong><span style="FONT-SIZE: large"><font color=#008000>6.数据库索引</font></span></strong></div>
<div></div>
<div><strong>适用范围：</strong>大数据量的增删改查</div>
<div></div>
<div><strong>基本原理及要点：</strong>利用数据的设计实现方法，对海量数据的增删改查进行处理。</div>
<div><strong>扩展：</strong></div>
<div><strong>问题实例：</strong></div>
<div></div>
<div></div>
<div><strong><span style="FONT-SIZE: large"><font color=#008000>7.倒排索引(Inverted index)</font></span></strong></div>
<div></div>
<div><strong>适用范围：</strong>搜索引擎，关键字查询</div>
<div></div>
<div><strong>基本原理及要点：</strong>为何叫倒排索引？一种索引方法，被用来存储在全文搜索下某个单词在一个文档或者一组文档中的存储位置的映射。</div>
<div></div>
<div>以英文为例，下面是要被索引的文本：</div>
<div>T0 = "it is what it is"</div>
<div>T1 = "what is it"</div>
<div>T2 = "it is a banana"</div>
<div>我们就能得到下面的反向文件索引：</div>
<div>"a": {2}</div>
<div>"banana": {2}</div>
<div>"is": {0, 1, 2}</div>
<div>"it": {0, 1, 2}</div>
<div>"what": {0, 1}</div>
<div>检索的条件"what", "is" 和 "it" 将对应集合的交集。</div>
<div></div>
<div>正 向索引开发出来用来存储每个文档的单词的列表。 正向索引的查询往往满足每个文档有序频繁的全文查询和每个单词在校验文档中的验证这样的查询。在正向索引中，文档占据了中心的位置，每个文档指向了一个它 所包含的索引项的序列。也就是说文档指向了它包含的那些单词，而反向索引则是单词指向了包含它的文档，很容易看到这个反向的关系。</div>
<div></div>
<div><strong>扩展：</strong></div>
<div></div>
<div><strong>问题实例</strong>：文档检索系统，查询那些文件包含了某单词，比如常见的学术论文的关键字搜索。</div>
<div></div>
<div><strong><span style="FONT-SIZE: large"><font color=#008000>8.外排序</font></span></strong></div>
<div></div>
<div><strong>适用范围</strong>：大数据的排序，去重</div>
<div></div>
<div><strong>基本原理及要点：</strong>外排序的归并方法，置换选择 败者树原理，最优归并树</div>
<div></div>
<div><strong>扩展：</strong></div>
<div></div>
<div><strong>问题实例：</strong></div>
<div>1).有一个1G大小的一个文件，里面每一行是一个词，词的大小不超过16个字节，内存限制大小是1M。返回频数最高的100个词。</div>
<div></div>
<div>这个数据具有很明显的特点，词的大小为16个字节，但是内存只有1m做hash有些不够，所以可以用来排序。内存可以当输入缓冲区使用。</div>
<div></div>
<div><span style="FONT-SIZE: large"><font color=#008000><strong>9.trie树</strong></font></span><strong><br></strong></div>
<div><strong>适用范围</strong>：数据量大，重复多，但是数据种类小可以放入内存</div>
<div></div>
<div><strong>基本原理及要点</strong>：实现方式，节点孩子的表示方式</div>
<div></div>
<div><strong>扩展：</strong>压缩实现。</div>
<div></div>
<div><strong>问题实例：</strong></div>
<div>1).有10个文件，每个文件1G， 每个文件的每一行都存放的是用户的query，每个文件的query都可能重复。要你按照query的频度排序 。</div>
<div></div>
<div>2).1000万字符串，其中有些是相同的(重复),需要把重复的全部去掉，保留没有重复的字符串。请问怎么设计和实现？</div>
<div></div>
<div>3).寻找热门查询：查询串的重复度比较高，虽然总数是1千万，但如果除去重复后，不超过3百万个，每个不超过255字节。</div>
<div><strong><span style="FONT-SIZE: large"><font color=#008000>10.分布式处理 mapreduce</font></span></strong><font color=#008000><span style="LINE-HEIGHT: 28px; FONT-SIZE: large"><strong><br></strong></span></font></div>
<div><strong>适用范围</strong>：数据量大，但是数据种类小可以放入内存</div>
<div></div>
<div><strong>基本原理及要点：</strong>将数据交给不同的机器去处理，数据划分，结果归约。</div>
<div></div>
<div><strong>扩展：</strong></div>
<div></div>
<div><strong>问题实例：</strong></div>
<div></div>
<div>1).The canonical example application of MapReduce is a process to count the appearances of</div>
<div></div>
<div>each different word in a set of documents:</div>
<div>void map(String name, String document):</div>
<div>&nbsp;&nbsp; // name: document name</div>
<div>&nbsp;&nbsp; // document: document contents</div>
<div>&nbsp;&nbsp; for each word w in document:</div>
<div>&nbsp;&nbsp; EmitIntermediate(w, 1);</div>
<div></div>
<div>void reduce(String word, Iterator partialCounts):</div>
<div>&nbsp;&nbsp; // key: a word</div>
<div>&nbsp;&nbsp; // values: a list of aggregated partial counts</div>
<div>&nbsp;&nbsp; int result = 0;</div>
<div>&nbsp;&nbsp; for each v in partialCounts:</div>
<div>&nbsp;&nbsp; result += ParseInt(v);</div>
<div>&nbsp;&nbsp; Emit(result);</div>
<div>Here, each document is split in words, and each word is counted initially with a "1" value by</div>
<div></div>
<div>the Map function, using the word as the result key. The framework puts together all the pairs</div>
<div></div>
<div>with the same key and feeds them to the same call to Reduce, thus this function just needs to</div>
<div></div>
<div>sum all of its input values to find the total appearances of that word.</div>
<div></div>
<div>2).海量数据分布在100台电脑中，想个办法高效统计出这批数据的TOP10。</div>
<div></div>
<div>3).一共有N个机器，每个机器上有N个数。每个机器最多存O(N)个数并对它们操作。如何找到N^2个数的中数(median)？</div>
<div></div>
<div></div>
<div><strong><span style="FONT-SIZE: x-large"><font color=#008000>经典问题分析</font></span></strong></div>
<div></div>
<div><strong>上千万or亿数据（有重复），统计其中出现次数最多的前N个数据,分两种情况：可一次读入内存，不可一次读入。</strong></div>
<div></div>
<div><strong>可用思路：</strong>trie树+堆，数据库索引，划分子集分别统计，hash，分布式计算，近似统计，外排序</div>
<div></div>
<div>所 谓的是否能一次读入内存，实际上应该指去除重复后的数据量。如果去重后数据可以放入内存，我们可以为数据建立字典，比如通过 map，hashmap，trie，然后直接进行统计即可。当然在更新每条数据的出现次数的时候，我们可以利用一个堆来维护出现次数最多的前N个数据，当 然这样导致维护次数增加，不如完全统计后在求前N大效率高。</div>
<div></div>
<div>如果数据无法放入内存。一方面我们可以考虑上面的字典方法能否被改进以适应这种情形，可以做的改变就是将字典存放到硬盘上，而不是内存，这可以参考数据库的存储方法。</div>
<div></div>
<div>当 然还有更好的方法，就是可以采用分布式计算，基本上就是map-reduce过程，首先可以根据数据值或者把数据hash(md5)后的值，将数据按照范 围划分到不同的机子，最好可以让数据划分后可以一次读入内存，这样不同的机子负责处理各种的数值范围，实际上就是map。得到结果后，各个机子只需拿出各 自的出现次数最多的前N个数据，然后汇总，选出所有的数据中出现次数最多的前N个数据，这实际上就是reduce过程。</div>
<div></div>
<div>实 际上可能想直接将数据均分到不同的机子上进行处理，这样是无法得到正确的解的。因为一个数据可能被均分到不同的机子上，而另一个则可能完全聚集到一个机子 上，同时还可能存在具有相同数目的数据。比如我们要找出现次数最多的前100个，我们将1000万的数据分布到10台机器上，找到每台出现次数最多的前 100个，归并之后这样不能保证找到真正的第100个，因为比如出现次数最多的第100个可能有1万个，但是它被分到了10台机子，这样在每台上只有1千 个，假设这些机子排名在1000个之前的那些都是单独分布在一台机子上的，比如有1001个，这样本来具有1万个的这个就会被淘汰，即使我们让每台机子选 出出现次数最多的1000个再归并，仍然会出错，因为可能存在大量个数为1001个的发生聚集。因此不能将数据随便均分到不同机子上，而是要根据hash 后的值将它们映射到不同的机子上处理，让不同的机器处理一个数值范围。</div>
<div></div>
<div>而外排序的方法会消耗大量的IO，效率不会很高。而上面的分布式方法，也可以用于单机版本，也就是将总的数据根据值的范围，划分成多个不同的子文件，然后逐个处理。处理完毕之后再对这些单词的及其出现频率进行一个归并。实际上就可以利用一个外排序的归并过程。<br><br>另外还可以考虑近似计算，也就是我们可以通过结合自然语言属性，只将那些真正实际中出现最多的那些词作为一个字典，使得这个规模可以放入内存。<br></div>
转载请注明出处：http://duanple.blog.163.com/blog/static/7097176720091026458369/<br>作者phylips@bmy<br>
<img src ="http://www.cppblog.com/koson/aggbug/109734.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/koson/" target="_blank">koson</a> 2010-03-15 14:40 <a href="http://www.cppblog.com/koson/archive/2010/03/15/109734.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>POJ 2002</title><link>http://www.cppblog.com/koson/archive/2010/03/14/109676.html</link><dc:creator>koson</dc:creator><author>koson</author><pubDate>Sun, 14 Mar 2010 06:30:00 GMT</pubDate><guid>http://www.cppblog.com/koson/archive/2010/03/14/109676.html</guid><wfw:comment>http://www.cppblog.com/koson/comments/109676.html</wfw:comment><comments>http://www.cppblog.com/koson/archive/2010/03/14/109676.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/koson/comments/commentRss/109676.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/koson/services/trackbacks/109676.html</trackback:ping><description><![CDATA[<p>在一个坐标内给出至多1000个不同的点，要求可以形成正方形的个数。总体思路是两两枚举不同的点对，然后求出跟这两个点可以形成正方形的另外两个点，然后再查找这两个点是否存在，查找可以使用哈希或者二分，结果显示哈希的效率比二分的高。</p>
<img src ="http://www.cppblog.com/koson/aggbug/109676.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/koson/" target="_blank">koson</a> 2010-03-14 14:30 <a href="http://www.cppblog.com/koson/archive/2010/03/14/109676.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我的pku层次分类</title><link>http://www.cppblog.com/koson/archive/2010/03/14/109657.html</link><dc:creator>koson</dc:creator><author>koson</author><pubDate>Sun, 14 Mar 2010 04:23:00 GMT</pubDate><guid>http://www.cppblog.com/koson/archive/2010/03/14/109657.html</guid><wfw:comment>http://www.cppblog.com/koson/comments/109657.html</wfw:comment><comments>http://www.cppblog.com/koson/archive/2010/03/14/109657.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/koson/comments/commentRss/109657.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/koson/services/trackbacks/109657.html</trackback:ping><description><![CDATA[本来在google doc上编辑的，但反应很慢，只好搬来这里了<br><br goog_docs_charindex="29">转贴 ACM的算法（觉得很好，有层次感） <br goog_docs_charindex="51">OJ上的一些水题(可用来练手和增加自信) &nbsp;<br goog_docs_charindex="74">(poj3299*,&nbsp;&nbsp; &nbsp;poj2159*, &nbsp;&nbsp; &nbsp;poj2739*&nbsp;&nbsp; &nbsp;,poj1083*&nbsp;&nbsp; &nbsp;,poj2262*&nbsp;&nbsp; &nbsp;,poj1503* (高精度,前导零),poj3006*(素数,暴力),poj2255*(递归), &nbsp;<br goog_docs_charindex="192">poj3094*) &nbsp;<br goog_docs_charindex="204">&nbsp;<br goog_docs_charindex="206">&nbsp;<br goog_docs_charindex="208">初期: &nbsp;<br goog_docs_charindex="214">一.基本算法:&nbsp; &nbsp;<br goog_docs_charindex="225">&nbsp;&nbsp;&nbsp;&nbsp; (1)枚举. (poj1753*(bfs)&nbsp;&nbsp; &nbsp;,poj2965*(推论||bfs) ) &nbsp;<br goog_docs_charindex="278">&nbsp;&nbsp;&nbsp;&nbsp; (2)贪心(poj1328*(区间段),&nbsp;&nbsp; &nbsp;poj2109*(long double)&nbsp;&nbsp; &nbsp;,poj2586*(分情况讨论) &nbsp;<br goog_docs_charindex="351">&nbsp;&nbsp;&nbsp;&nbsp; (3)递归和分治法.&nbsp; &nbsp;<br goog_docs_charindex="370">&nbsp;&nbsp;&nbsp;&nbsp; (4)递推.&nbsp; &nbsp;<br goog_docs_charindex="385">&nbsp;&nbsp;&nbsp;&nbsp; (5)构造法.(poj3295*(栈) &nbsp;<br goog_docs_charindex="412">&nbsp;&nbsp;&nbsp;&nbsp; (6)模拟法.(poj1068*&nbsp;&nbsp; &nbsp;,poj2632*&nbsp;&nbsp; &nbsp;,poj1573*&nbsp;&nbsp; &nbsp;,poj2993,poj2996) &nbsp;<br goog_docs_charindex="483">二.图算法:&nbsp; &nbsp;<br goog_docs_charindex="493">&nbsp;&nbsp;&nbsp;&nbsp; (1)图的深度优先遍历和广度优先遍历.&nbsp; &nbsp;<br goog_docs_charindex="521">&nbsp;&nbsp;&nbsp;&nbsp; (2)最短路径算法(heap+dijkstra,dijkstra,bellman-ford,floyd,)&nbsp; &nbsp;<br goog_docs_charindex="583">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; poj1860<br>&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; poj3259*(bellman-ford 换了种描述而已)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; poj1062*(枚举m种等级即可,每种求最短路)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; poj2253*(dijkstra思想)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; poj1125*<br>&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; poj2240*(floyd)<br>&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; poj 3013 #(dijkstra+heap实现的最小优先队列+邻接表) &nbsp; ) &nbsp;<br goog_docs_charindex="714">&nbsp;&nbsp;&nbsp;&nbsp; (3)最小生成树算法(prim,kruskal) &nbsp;<br goog_docs_charindex="746">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj1789*,&nbsp;&nbsp; &nbsp;poj2485*(prim最大边),&nbsp;&nbsp; &nbsp;poj1258*(prime),&nbsp;&nbsp; &nbsp;poj3026 ,poj 1251*,poj 1861*(生成树的最大边) ) &nbsp;<br goog_docs_charindex="852">&nbsp;&nbsp;&nbsp;&nbsp; (4)拓扑排序<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; poj1094 #(深搜，以结点访问结束时间降序确定拓扑顺序)<br goog_docs_charindex="877">&nbsp;&nbsp;&nbsp;&nbsp; (5)二分图的最大匹配 (匈牙利算法) (poj3041*(行列匹配),poj3020) &nbsp;<br goog_docs_charindex="929">&nbsp;&nbsp;&nbsp;&nbsp; (6)最大流的增广路算法(KM算法). (poj3436,&nbsp;&nbsp; poj 1273 #(基础,使用edmonds-karp算法) ,poj 1459 # (基础构图),poj 1149 # (经典构图) )&nbsp; <br goog_docs_charindex="974">三.数据结构.&nbsp; &nbsp;<br goog_docs_charindex="985">&nbsp;&nbsp;&nbsp;&nbsp; (1)串 (poj1035*(brute force)&nbsp;&nbsp; &nbsp;,poj3080*(brute force c string函数使用)&nbsp;&nbsp; &nbsp;,poj1936) &nbsp;<br goog_docs_charindex="1072">&nbsp;&nbsp;&nbsp;&nbsp; (2)排序(快排、归并排(与逆序数有关)、堆排) (poj2388*(qsort),poj2299*(归并)) &nbsp;<br goog_docs_charindex="1135">&nbsp;&nbsp;&nbsp;&nbsp; (3)简单并查集的应用.&nbsp; 2492*(设置每个虫的一个异性虫) ,1182 #(通过设置与结点的相对关系来实现，要仔细推导), 1988 #( 通过设置辅助数组保存结果值，并在查找过程中进行更新) <br goog_docs_charindex="1174">&nbsp;&nbsp;&nbsp;&nbsp; (4)哈希表和二分查找等高效查找法(数的Hash,串的Hash)&nbsp;&nbsp;&nbsp; &nbsp;<br goog_docs_charindex="1217">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj3349*(复杂度超高,不用STL写cmp更快),poj3274,POJ2151,&nbsp;&nbsp; &nbsp;poj1840*#(hash# || bsearch)&nbsp;&nbsp; &nbsp;,poj2002#(hash,hash表保存点信息，枚举两两点对，查找另外两点是否存在,也可使用二分查找，二分效率比较低),&nbsp;&nbsp; &nbsp;poj2503*(经典题目)&nbsp;&nbsp; &nbsp;,poj 2513，poj2418#(用二叉查找树插入，插入时如果找到相同时则记录数加一，否则作为新的结点插入，最后用中序遍历输出) ) &nbsp;<br goog_docs_charindex="1385">&nbsp;&nbsp;&nbsp;&nbsp; (5)哈夫曼树(poj3253 *(use stl priority_queue and __int64) &nbsp;<br goog_docs_charindex="1446">&nbsp;&nbsp;&nbsp;&nbsp; (6)堆(poj 2442 #,每次对两个序列用堆在o(nlogn)时间内求出前n个最小的数，然后这个作为新的序列与后面的输入序列作重复处理，实现取前n个数我的方法由于可能取到重复值，所以加了一个哈希表并于判重,&nbsp; poj 2051 #(跟有序链表的K路归并一样，可参照CLRS) )<br goog_docs_charindex="1459">&nbsp;&nbsp;&nbsp;&nbsp; (7)trie树(静态建树、动态建树) (poj2513*(并查集+trie+欧拉图) poj 3630(用一个结点数组静态模拟动态建树) <br goog_docs_charindex="1535">四.简单搜索&nbsp; &nbsp;<br goog_docs_charindex="1545">&nbsp;&nbsp;&nbsp;&nbsp; (1)深度优先搜索 (poj2488*(递归),&nbsp;&nbsp; &nbsp;poj3083,&nbsp;&nbsp; &nbsp;poj3009*(dfs剪枝),&nbsp;&nbsp; &nbsp;poj1321*(dfs),&nbsp;&nbsp; &nbsp;poj2251*(bfs)) &nbsp;<br goog_docs_charindex="1645">&nbsp;&nbsp;&nbsp;&nbsp; (2)广度优先搜索(poj3278*(bfs 使用set存储已访问结点使用find函数NlogN),&nbsp;&nbsp; &nbsp;poj1426,&nbsp;&nbsp; &nbsp;poj3126*( ),&nbsp;&nbsp; &nbsp;poj3087*(每次只有一个分支的搜索).poj3414*(BFS打印路径) &nbsp;<br goog_docs_charindex="1774">&nbsp;&nbsp;&nbsp;&nbsp; (3)简单搜索技巧和剪枝(poj2531*(bfs+重复状态剪枝,另可以随机化算法,动态规划(还没试过) ),&nbsp;&nbsp; &nbsp;poj1416*(bfs+简单剪枝),&nbsp;&nbsp; &nbsp;poj2676,1129) &nbsp;<br goog_docs_charindex="1877">五.动态规划&nbsp; &nbsp;<br goog_docs_charindex="1887">&nbsp;&nbsp;&nbsp;&nbsp; (1)背包问题. (poj1837,poj1276) &nbsp;<br goog_docs_charindex="1921">&nbsp;&nbsp;&nbsp;&nbsp; (2)型如下表的简单DP(可参考lrj的书 page149):&nbsp; &nbsp;<br goog_docs_charindex="1961">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.E[j]=opt{D+w(i,j)} (poj3267,poj1836,poj1260,poj2533) &nbsp;<br goog_docs_charindex="2025">&nbsp;<br goog_docs_charindex="2027">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.E[i,j]=opt{D[i-1,j]+xi,D[i,j-1]+yj,D[i-1][j-1]+zij} (最长公共子序列) &nbsp;<br goog_docs_charindex="2100">&nbsp;<br goog_docs_charindex="2102">&nbsp;&nbsp;&nbsp; &nbsp;<br goog_docs_charindex="2108">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj3176,poj1080,poj1159) &nbsp;<br goog_docs_charindex="2145">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.C[i,j]=w[i,j]+opt{C[i,k-1]+C[k,j]}.(最优二分检索树问题)&nbsp; &nbsp;<br goog_docs_charindex="2204">六.数学&nbsp; &nbsp;<br goog_docs_charindex="2212">&nbsp;&nbsp;&nbsp;&nbsp; (1)组合数学:&nbsp; &nbsp;<br goog_docs_charindex="2229">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.加法原理和乘法原理.&nbsp; &nbsp;<br goog_docs_charindex="2253">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.排列组合.&nbsp; &nbsp;<br goog_docs_charindex="2272">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.递推关系.&nbsp; &nbsp;<br goog_docs_charindex="2291">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (POJ3252,poj1850*(组合公式),poj1019*(等差数列),poj1942*(组合,T数) &nbsp;<br goog_docs_charindex="2358">&nbsp;&nbsp;&nbsp;&nbsp; (2)数论.&nbsp; &nbsp;<br goog_docs_charindex="2373">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.素数与整除问题&nbsp; &nbsp;<br goog_docs_charindex="2394">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.进制位.&nbsp; &nbsp;<br goog_docs_charindex="2412">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.同余模运算. &nbsp;<br goog_docs_charindex="2431">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj2635*(大整数模), poj3292,poj1845,poj2115) &nbsp;<br goog_docs_charindex="2485">&nbsp;&nbsp;&nbsp;&nbsp; (3)计算方法.&nbsp; &nbsp;<br goog_docs_charindex="2502">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.二分法求解单调函数相关知识.(poj3273*(),&nbsp;&nbsp; &nbsp;poj3258*,&nbsp;&nbsp; &nbsp;poj1905*(),&nbsp;&nbsp; &nbsp;poj3122*()) (数值计算的....) <br goog_docs_charindex="2595">七.计算几何学.&nbsp; &nbsp;<br goog_docs_charindex="2607">&nbsp;&nbsp;&nbsp;&nbsp; (1)几何公式. &nbsp;<br goog_docs_charindex="2623">&nbsp;&nbsp;&nbsp;&nbsp; (2)叉积和点积的运用(如线段相交的判定,点到线段的距离等). (poj2031*(最小生成树),poj1039) <br goog_docs_charindex="2687">&nbsp;<br goog_docs_charindex="2689">&nbsp; <br goog_docs_charindex="2692">&nbsp;&nbsp;&nbsp;&nbsp; (3)多边型的简单算法(求面积)和相关判定(点在多边型内,多边型是否相交)&nbsp; &nbsp;<br goog_docs_charindex="2738">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj1408*(求四边形面积),&nbsp;&nbsp; &nbsp;poj1584) &nbsp;<br goog_docs_charindex="2780">&nbsp;&nbsp;&nbsp;&nbsp; (4)凸包.&nbsp; (poj2187*(求法,排序使用堆排,或快排) poj1113*()) &nbsp;<br goog_docs_charindex="2832">&nbsp;<br goog_docs_charindex="2834">***************************************************************************** <br goog_docs_charindex="2913">&nbsp;<br goog_docs_charindex="2915">中级: &nbsp;<br goog_docs_charindex="2921">一.基本算法:&nbsp; &nbsp;<br goog_docs_charindex="2932">&nbsp;&nbsp;&nbsp;&nbsp; (1)C++的标准模版库的应用. (poj3096*,&nbsp;&nbsp; &nbsp;poj3007) &nbsp;<br goog_docs_charindex="2979">&nbsp;&nbsp;&nbsp;&nbsp; (2)较为复杂的模拟题的训练(poj3393,poj1472,poj3371,poj1027,poj2706) &nbsp;<br goog_docs_charindex="3042">二.图算法:&nbsp; &nbsp;<br goog_docs_charindex="3052">&nbsp;&nbsp;&nbsp;&nbsp; (1)差分约束系统的建立和求解. (poj1201,poj2983,poj1364*) &nbsp;<br goog_docs_charindex="3103">&nbsp;&nbsp;&nbsp;&nbsp; (2)最小费用最大流(poj2516,poj2195) &nbsp;<br goog_docs_charindex="3138">&nbsp;&nbsp;&nbsp;&nbsp; (3)双连通分量(poj2942 ,poj 3177) &nbsp;<br goog_docs_charindex="3173">&nbsp;&nbsp;&nbsp;&nbsp; (4)强连通分支及其缩点.(poj 2762*(单向连通图判断 1983ms ,该怎么优化),poj 2553* ,poj 1236*,)&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; poj 2186 #(使用trajan求强连通分量，并将每个分量缩成一点形成新的图，最后求出度为0的缩点的个数，如果大于等于2个，则结果为0，否则对应<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 分量的原结点个数)<br goog_docs_charindex="3260">&nbsp;&nbsp;&nbsp;&nbsp; (5)图的割边和割点( poj 3177)&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; poj 1523 #(每次搜到一个割点i,令tag[i]++,最后输出割点i,连通区域的个数为tag[i]+1,并不需要每次对图进行搜索求连通区域数量)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; poj 3352 #(先找出桥，去掉桥将其余的连通分支缩成点，再把桥加到缩点图上形成一棵树，求出度数为1的点即叶子结点的数目ret,结果为(ret+1)/2)<br goog_docs_charindex="3307">&nbsp;&nbsp;&nbsp;&nbsp; (6)最小割模型、网络流规约(poj3308, ) &nbsp;<br goog_docs_charindex="3340">三.数据结构.&nbsp; &nbsp;<br goog_docs_charindex="3351">&nbsp;&nbsp;&nbsp;&nbsp; (1)线段树. (poj2528,poj2828,&nbsp;&nbsp; &nbsp;poj2777*,&nbsp;&nbsp; &nbsp;poj2886,poj2750,poj2985) &nbsp;<br goog_docs_charindex="3425">&nbsp;&nbsp;&nbsp;&nbsp; (2)静态二叉检索树. (poj2482,poj2352) &nbsp;<br goog_docs_charindex="3462">&nbsp;&nbsp;&nbsp;&nbsp; (3)树状树组(poj1195*(二级树状,作简单运算),&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;poj3321 ,poj2481*,&nbsp;&nbsp; &nbsp;poj2155) &nbsp;<br goog_docs_charindex="3537">&nbsp;&nbsp;&nbsp;&nbsp; (4)RMQ. (poj3264*,&nbsp;&nbsp; &nbsp;poj3368*(原数组的转换) &nbsp;<br goog_docs_charindex="3583">&nbsp;&nbsp;&nbsp;&nbsp; (5)并查集的高级应用. (poj1703*,2492) &nbsp;<br goog_docs_charindex="3619">&nbsp;&nbsp;&nbsp;&nbsp; (6)KMP算法. (poj1961*,poj2406*) 2752* (利用next函数的原理) <br goog_docs_charindex="3675">四.搜索&nbsp; &nbsp;<br goog_docs_charindex="3683">&nbsp;&nbsp;&nbsp;&nbsp; (1)最优化剪枝和可行性剪枝&nbsp; &nbsp;<br goog_docs_charindex="3706">&nbsp;&nbsp;&nbsp;&nbsp; (2)搜索的技巧和优化<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; poj3411<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; poj1724 #( dfs＋剪枝，因为有重边，所以采用邻接表来表示边)<br goog_docs_charindex="3743">&nbsp;&nbsp;&nbsp;&nbsp; (3)记忆化搜索(poj3373,poj1691) &nbsp;<br goog_docs_charindex="3776">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br goog_docs_charindex="3784">五.动态规划&nbsp; &nbsp;<br goog_docs_charindex="3794">&nbsp;&nbsp;&nbsp;&nbsp; (1)较为复杂的动态规划(如动态规划解特别的施行商问题等) &nbsp;<br goog_docs_charindex="3831">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj1191,poj1054,poj3280,poj2029,poj2948,poj1925,poj3034) &nbsp;<br goog_docs_charindex="3900">&nbsp;&nbsp;&nbsp;&nbsp; (2)记录状态的动态规划. (POJ3254,poj2411,poj1185) &nbsp;<br goog_docs_charindex="3947">&nbsp;&nbsp;&nbsp;&nbsp; (3)树型动态规划(poj2057,poj1947,poj2486,poj3140) &nbsp;<br goog_docs_charindex="3997">六.数学&nbsp; &nbsp;<br goog_docs_charindex="4005">&nbsp;&nbsp;&nbsp;&nbsp; (1)组合数学:&nbsp; &nbsp;<br goog_docs_charindex="4022">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.容斥原理.&nbsp; &nbsp;<br goog_docs_charindex="4041">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.抽屉原理.&nbsp; &nbsp;<br goog_docs_charindex="4060">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.置换群与Polya定理(poj1286,poj2409,poj3270,poj1026).&nbsp; &nbsp;<br goog_docs_charindex="4119">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.递推关系和母函数.&nbsp; &nbsp;<br goog_docs_charindex="4142">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br goog_docs_charindex="4153">&nbsp;&nbsp;&nbsp;&nbsp; (2)数学.&nbsp; &nbsp;<br goog_docs_charindex="4168">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.高斯消元法(poj2947,poj1487, poj2065,poj1166,poj1222) &nbsp;<br goog_docs_charindex="4228">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.概率问题. (poj3071,poj3440) &nbsp;<br goog_docs_charindex="4264">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.GCD、扩展的欧几里德(中国剩余定理) (poj3101)&nbsp; &nbsp;<br goog_docs_charindex="4307">&nbsp;&nbsp;&nbsp;&nbsp; (3)计算方法.&nbsp; &nbsp;<br goog_docs_charindex="4324">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.0/1分数规划. (poj2976) &nbsp;<br goog_docs_charindex="4355">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.三分法求解单峰(单谷)的极值.&nbsp; &nbsp;<br goog_docs_charindex="4384">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.矩阵法(poj3150,poj3422,poj3070) &nbsp;<br goog_docs_charindex="4425">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.迭代逼近(poj3301) &nbsp;<br goog_docs_charindex="4451">&nbsp;&nbsp;&nbsp;&nbsp; (4)随机化算法(poj3318*&nbsp;&nbsp; &nbsp;,poj2454) &nbsp;<br goog_docs_charindex="4489">&nbsp;&nbsp;&nbsp;&nbsp; (5)杂题. &nbsp;<br goog_docs_charindex="4503">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj1870,poj3296,poj3286,poj1095) &nbsp;<br goog_docs_charindex="4548">七.计算几何学.&nbsp; &nbsp;<br goog_docs_charindex="4560">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)坐标离散化.&nbsp; &nbsp;<br goog_docs_charindex="4581">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)扫描线算法(例如求矩形的面积和周长并,常和线段树或堆一起使用).&nbsp; &nbsp;<br goog_docs_charindex="4628">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj1765,poj1177,poj1151,poj3277,poj2280,poj3004) &nbsp;<br goog_docs_charindex="4692">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3)多边形的内核(半平面交)(poj3130,poj3335) &nbsp;<br goog_docs_charindex="4735">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4)几何工具的综合应用.(poj1819,poj1066,poj2043,poj3227,poj2165,poj3429 <br goog_docs_charindex="4806">&nbsp;<br goog_docs_charindex="4808">) &nbsp;<br goog_docs_charindex="4812">高级: &nbsp;<br goog_docs_charindex="4818">一.基本算法要求:&nbsp;&nbsp; &nbsp;<br goog_docs_charindex="4832">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)代码快速写成,精简但不失风格&nbsp;&nbsp; &nbsp;<br goog_docs_charindex="4860">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj2525,poj1684,poj1421,poj1048,poj2050,poj3306) &nbsp;<br goog_docs_charindex="4922">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)保证正确性和高效性.&nbsp; poj3434 &nbsp;<br goog_docs_charindex="4953">二.图算法:&nbsp; &nbsp;<br goog_docs_charindex="4963">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)度限制最小生成树和第K最短路. (poj1639) &nbsp;<br goog_docs_charindex="5000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)最短路,最小生成树,二分图,最大流问题的相关理论(主要是模型建立和求解) &nbsp;<br goog_docs_charindex="5048">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj3155, poj2112,poj1966,poj3281,poj1087,poj2289,poj3216,poj2446 &nbsp;<br goog_docs_charindex="5125">&nbsp;<br goog_docs_charindex="5127">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3)最优比率生成树.&nbsp; (poj2728) &nbsp;<br goog_docs_charindex="5158">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4)最小树形图(poj3164) &nbsp;<br goog_docs_charindex="5184">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5)次小生成树.&nbsp; &nbsp;<br goog_docs_charindex="5203">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6)无向图、有向图的最小环&nbsp;&nbsp;&nbsp; &nbsp;<br goog_docs_charindex="5229">三.数据结构.&nbsp;&nbsp; &nbsp;<br goog_docs_charindex="5241">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)trie图的建立和应用. (poj2778) &nbsp;<br goog_docs_charindex="5275">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)LCA和RMQ问题(LCA(最近公共祖先问题) 有离线算法(并查集+dfs) 和 在线算法 <br goog_docs_charindex="5331">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (RMQ+dfs)).(poj1330*&nbsp;&nbsp; &nbsp;(此题可以直接使用遍历出两条路径寻找最近相同点即可.并且比RMQ+DFS还快) &nbsp;<br goog_docs_charindex="5407">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3)双端队列和它的应用(维护一个单调的队列,常常在动态规划中起到优化状态转移 <br goog_docs_charindex="5454">&nbsp;<br goog_docs_charindex="5456">的 &nbsp;<br goog_docs_charindex="5460">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 目的).&nbsp; (poj2823) &nbsp;<br goog_docs_charindex="5488">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4)左偏树(可合并堆).&nbsp;&nbsp; &nbsp;<br goog_docs_charindex="5512">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5)后缀树(非常有用的数据结构,也是赛区考题的热点).&nbsp; &nbsp;<br goog_docs_charindex="5550">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj3415,poj3294) &nbsp;<br goog_docs_charindex="5579">四.搜索&nbsp;&nbsp; &nbsp;<br goog_docs_charindex="5588">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)较麻烦的搜索题目训练(poj1069,poj3322,poj1475,poj1924,poj2049,poj3426) <br goog_docs_charindex="5658">&nbsp;<br goog_docs_charindex="5660">&nbsp; <br goog_docs_charindex="5663">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)广搜的状态优化:利用M进制数存储状态、转化为串用hash表判重、按位压缩存储 <br goog_docs_charindex="5712">&nbsp;<br goog_docs_charindex="5714">状态、双向广搜、A*算法. (poj1768,poj1184,poj1872,poj1324,poj2046,poj1482) &nbsp;<br goog_docs_charindex="5780">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3)深搜的优化:尽量用位运算、一定要加剪枝、函数参数尽可能少、层数不易过大 <br goog_docs_charindex="5826">&nbsp;<br goog_docs_charindex="5828">、可以考虑双向搜索或者是轮换搜索、IDA*算法. (poj3131,poj2870,poj2286) &nbsp;<br goog_docs_charindex="5881">五.动态规划&nbsp;&nbsp; &nbsp;<br goog_docs_charindex="5892">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)需要用数据结构优化的动态规划. &nbsp;<br goog_docs_charindex="5919">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj2754,poj3378,poj3017) &nbsp;<br goog_docs_charindex="5956">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)四边形不等式理论.&nbsp; &nbsp;<br goog_docs_charindex="5978">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3)较难的状态DP(poj3133) &nbsp;<br goog_docs_charindex="6006">六.数学&nbsp;&nbsp; &nbsp;<br goog_docs_charindex="6015">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)组合数学.&nbsp; &nbsp;<br goog_docs_charindex="6033">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.MoBius反演(poj2888,poj2154) &nbsp;<br goog_docs_charindex="6071">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.偏序关系理论.&nbsp; &nbsp;<br goog_docs_charindex="6092">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)博奕论.&nbsp; &nbsp;<br goog_docs_charindex="6109">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.极大极小过程(poj3317,poj1085) &nbsp;<br goog_docs_charindex="6145">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.Nim问题.&nbsp; &nbsp;<br goog_docs_charindex="6165">七.计算几何学.&nbsp;&nbsp; &nbsp;<br goog_docs_charindex="6178">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)半平面求交(poj3384,poj2540) &nbsp;<br goog_docs_charindex="6212">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)可视图的建立(poj2966) &nbsp;<br goog_docs_charindex="6239">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3)点集最小圆覆盖.&nbsp; &nbsp;<br goog_docs_charindex="6260">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4)对踵点(poj2079) &nbsp;<br goog_docs_charindex="6284">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 八.综合题. &nbsp;<br goog_docs_charindex="6299">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (poj3109,poj1478,poj1462,poj2729,poj2048,poj3336,poj3315,poj2148,poj1263         <img src ="http://www.cppblog.com/koson/aggbug/109657.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/koson/" target="_blank">koson</a> 2010-03-14 12:23 <a href="http://www.cppblog.com/koson/archive/2010/03/14/109657.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hash算法大全</title><link>http://www.cppblog.com/koson/archive/2010/03/11/109446.html</link><dc:creator>koson</dc:creator><author>koson</author><pubDate>Thu, 11 Mar 2010 10:44:00 GMT</pubDate><guid>http://www.cppblog.com/koson/archive/2010/03/11/109446.html</guid><wfw:comment>http://www.cppblog.com/koson/comments/109446.html</wfw:comment><comments>http://www.cppblog.com/koson/archive/2010/03/11/109446.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/koson/comments/commentRss/109446.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/koson/services/trackbacks/109446.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: ***&nbsp;Hash算法大全&lt;br&gt;*&nbsp;推荐使用FNV1算法*&nbsp;@algorithm&nbsp;None*&nbsp;@author&nbsp;Goodzzp&nbsp;2006-11-20*&nbsp;@lastEdit&nbsp;Goodzzp&nbsp;2006-11-20&nbsp;*&nbsp;@editDetail&nbsp;Create*/pub...&nbsp;&nbsp;<a href='http://www.cppblog.com/koson/archive/2010/03/11/109446.html'>阅读全文</a><img src ="http://www.cppblog.com/koson/aggbug/109446.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/koson/" target="_blank">koson</a> 2010-03-11 18:44 <a href="http://www.cppblog.com/koson/archive/2010/03/11/109446.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>有层次PKU ACM分类</title><link>http://www.cppblog.com/koson/archive/2010/03/07/109138.html</link><dc:creator>koson</dc:creator><author>koson</author><pubDate>Sun, 07 Mar 2010 12:03:00 GMT</pubDate><guid>http://www.cppblog.com/koson/archive/2010/03/07/109138.html</guid><wfw:comment>http://www.cppblog.com/koson/comments/109138.html</wfw:comment><comments>http://www.cppblog.com/koson/archive/2010/03/07/109138.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/koson/comments/commentRss/109138.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/koson/services/trackbacks/109138.html</trackback:ping><description><![CDATA[<pre>OJ上的一些水题(可用来练手和增加自信)  <br>(poj3299,poj2159,poj2739,poj1083,poj2262,poj1503,poj3006,poj2255,poj3094)  <br>初期: <br>一.基本算法:  <br>     (1)枚举. (poj1753,poj2965)  <br>     (2)贪心(poj1328,poj2109,poj2586)  <br>     (3)递归和分治法.  <br>     (4)递推.  <br>     (5)构造法.(poj3295)  <br>     (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)  <br>二.图算法:  <br>     (1)图的深度优先遍历和广度优先遍历.  <br>     (2)最短路径算法(dijkstra,bellman-ford,floyd,heap+dijkstra)  <br>        (poj1860,poj3259,poj1062,poj2253,poj1125,poj2240)  <br>     (3)最小生成树算法(prim,kruskal)  <br>        (poj1789,poj2485,poj1258,poj3026)  <br>     (4)拓扑排序 (poj1094)  <br>     (5)二分图的最大匹配 (匈牙利算法) (poj3041,poj3020)  <br>     (6)最大流的增广路算法(KM算法). (poj1459,poj3436)  <br>三.数据结构 <br>     (1)串 (poj1035,poj3080,poj1936)  <br>     (2)排序(快排、归并排(与逆序数有关)、堆排) (poj2388,poj2299)  <br>     (3)简单并查集的应用.  <br>     (4)哈希表和二分查找等高效查找法(数的Hash,串的Hash)    <br>        (poj3349,poj3274,POJ2151,poj1840,poj2002,poj2503)  <br>     (5)哈夫曼树(poj3253)  <br>     (6)堆  <br>     (7)trie树(静态建树、动态建树) (poj2513)  <br>四.简单搜索 <br>     (1)深度优先搜索 (poj2488,poj3083,poj3009,poj1321,poj2251)  <br>     (2)广度优先搜索(poj3278,poj1426,poj3126,poj3087.poj3414)  <br>     (3)简单搜索技巧和剪枝(poj2531,poj1416,poj2676,1129)  <br>五.动态规划 <br>     (1)背包问题. (poj1837,poj1276)  <br>     (2)型如下表的简单DP(可参考lrj的书 page149):  <br>       1.E[j]=opt{D+w(i,j)} (poj3267,poj1836,poj1260,poj2533)  <br>       2.E[i,j]=opt{D[i-1,j]+xi,D[i,j-1]+yj,D[i-1][j-1]+zij} (最长公共子序列)<br>    <br>         (poj3176,poj1080,poj1159)  <br>       3.C[i,j]=w[i,j]+opt{C[i,k-1]+C[k,j]}.(最优二分检索树问题)  <br>六.数学  <br>     (1)组合数学:  <br>        1.加法原理和乘法原理.  <br>        2.排列组合.  <br>        3.递推关系.  <br>          (POJ3252,poj1850,poj1019,poj1942)  <br>     (2)数论.  <br>        1.素数与整除问题  <br>        2.进制位.  <br>        3.同余模运算. <br>          (poj2635, poj3292,poj1845,poj2115)  <br>     (3)计算方法.  <br>        1.二分法求解单调函数相关知识.(poj3273,poj3258,poj1905,poj3122)  <br>七.计算几何学.  <br>     (1)几何公式. <br>     (2)叉积和点积的运用(如线段相交的判定,点到线段的距离等). <br>(poj2031,poj1039) <br>  <br>  <br>     (3)多边型的简单算法(求面积)和相关判定(点在多边型内,多边型是否相交)  <br>         (poj1408,poj1584)  <br>     (4)凸包.  (poj2187,poj1113)  <br>中级: <br>一.基本算法:<br>     (1)C++的标准模版库的应用. (poj3096,poj3007)  <br>     (2)较为复杂的模拟题的训练(poj3393,poj1472,poj3371,poj1027,poj2706)  <br>二.图算法:  <br>     (1)差分约束系统的建立和求解. (poj1201,poj2983)  <br>     (2)最小费用最大流(poj2516,poj2195)  <br>     (3)双连通分量(poj2942)  <br>     (4)强连通分支及其缩点.(poj2186)  <br>     (5)图的割边和割点(poj3352)  <br>     (6)最小割模型、网络流规约(poj3308, )  <br>三.数据结构.<br>     (1)线段树. (poj2528,poj2828,poj2777,poj2886,poj2750)  <br>     (2)静态二叉检索树. (poj2482,poj2352)  <br>     (3)树状树组(poj1195,poj3321)  <br>     (4)RMQ. (poj3264,poj3368)  <br>     (5)并查集的高级应用. (poj1703,2492)  <br>     (6)KMP算法. (poj1961,poj2406)  <br>四.搜索  <br>     (1)最优化剪枝和可行性剪枝  <br>     (2)搜索的技巧和优化 (poj3411,poj1724)  <br>     (3)记忆化搜索(poj3373,poj1691)  <br>      <br>五.动态规划 <br>     (1)较为复杂的动态规划(如动态规划解特别的施行商问题等)  <br>         (poj1191,poj1054,poj3280,poj2029,poj2948,poj1925,poj3034)  <br>     (2)记录状态的动态规划. (POJ3254,poj2411,poj1185)  <br>     (3)树型动态规划(poj2057,poj1947,poj2486,poj3140)  <br>六.数学  <br>     (1)组合数学:  <br>        1.容斥原理. <br>        2.抽屉原理. <br>        3.置换群与Polya定理(poj1286,poj2409,poj3270,poj1026).  <br>        4.递推关系和母函数.  <br>         <br>     (2)数学.  <br>        1.高斯消元法(poj2947,poj1487, poj2065,poj1166,poj1222)  <br>        2.概率问题. (poj3071,poj3440)  <br>        3.GCD、扩展的欧几里德(中国剩余定理) (poj3101)  <br>     (3)计算方法.  <br>        1.0/1分数规划. (poj2976)  <br>        2.三分法求解单峰(单谷)的极值.  <br>        3.矩阵法(poj3150,poj3422,poj3070)  <br>        4.迭代逼近(poj3301)  <br>     (4)随机化算法(poj3318,poj2454)  <br>     (5)杂题.<br>         (poj1870,poj3296,poj3286,poj1095)  <br>七.计算几何学.  <br>        (1)坐标离散化.  <br>        (2)扫描线算法(例如求矩形的面积和周长并,常和线段树或堆一起使用).  <br>            (poj1765,poj1177,poj1151,poj3277,poj2280,poj3004)  <br>        (3)多边形的内核(半平面交)(poj3130,poj3335)  <br>        (4)几何工具的综合应用.(poj1819,poj1066,poj2043,poj3227,poj2165)  <br>高级: <br>一.基本算法要求:   <br>      (1)代码快速写成,精简但不失风格   <br>          (poj2525,poj1684,poj1421,poj1048,poj2050,poj3306)  <br>      (2)保证正确性和高效性.  poj3434  <br>二.图算法:  <br>      (1)度限制最小生成树和第K最短路. (poj1639)  <br>      (2)最短路,最小生成树,二分图,最大流问题的相关理论(主要是模型建立和求解) <br>         (poj3155, poj2112,poj1966,poj3281,poj1087,poj2289,poj3216,poj2446  <br>      (3)最优比率生成树.  (poj2728)  <br>      (4)最小树形图(poj3164)  <br>      (5)次小生成树.  <br>      (6)无向图、有向图的最小环    <br>三.数据结构.   <br>      (1)trie图的建立和应用. (poj2778)  <br>      (2)LCA和RMQ问题(LCA(最近公共祖先问题) 有离线算法(并查集+dfs) 和 在线算<br>法 (RMQ+dfs)).(poj1330)  <br>      (3)双端队列和它的应用(维护一个单调的队列,常常在动态规划中起到优化状态转<br>移的目的).  (poj2823)  <br>      (4)左偏树(可合并堆).   <br>      (5)后缀树(非常有用的数据结构,也是赛区考题的热点).  <br>         (poj3415,poj3294)  <br>四.搜索   <br>      (1)较麻烦的搜索题目训练(poj1069,poj3322,poj1475,poj1924,poj2049,poj3426<br>) <br>      (2)广搜的状态优化:利用M进制数存储状态、转化为串用hash表判重、按位压缩存<br>储 <br>  <br>状态、双向广搜、A*算法. (poj1768,poj1184,poj1872,poj1324,poj2046,poj1482)  <br>      (3)深搜的优化:尽量用位运算、一定要加剪枝、函数参数尽可能少、层数不易过<br>大 <br>、可以考虑双向搜索或者是轮换搜索、IDA*算法. (poj3131,poj2870,poj2286)  <br>五.动态规划   <br>      (1)需要用数据结构优化的动态规划. <br>         (poj2754,poj3378,poj3017)  <br>      (2)四边形不等式理论.  <br>      (3)较难的状态DP(poj3133)  <br>六.数学   <br>      (1)组合数学.  <br>        1.MoBius反演(poj2888,poj2154)  <br>        2.偏序关系理论.  <br>      (2)博奕论.  <br>        1.极大极小过程(poj3317,poj1085)  <br>        2.Nim问题.  <br>七.计算几何学.   <br>      (1)半平面求交(poj3384,poj2540)  <br>      (2)可视图的建立(poj2966)  <br>      (3)点集最小圆覆盖.  <br>      (4)对踵点(poj2079)  <br>      八.综合题. <br>      <br>(poj3109,poj1478,poj1462,poj2729,poj2048,poj3336,poj3315,poj2148,poj1263 <br>  <br>)<br></pre><img src ="http://www.cppblog.com/koson/aggbug/109138.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/koson/" target="_blank">koson</a> 2010-03-07 20:03 <a href="http://www.cppblog.com/koson/archive/2010/03/07/109138.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>PKU题目分类</title><link>http://www.cppblog.com/koson/archive/2010/03/07/109137.html</link><dc:creator>koson</dc:creator><author>koson</author><pubDate>Sun, 07 Mar 2010 11:57:00 GMT</pubDate><guid>http://www.cppblog.com/koson/archive/2010/03/07/109137.html</guid><wfw:comment>http://www.cppblog.com/koson/comments/109137.html</wfw:comment><comments>http://www.cppblog.com/koson/archive/2010/03/07/109137.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/koson/comments/commentRss/109137.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/koson/services/trackbacks/109137.html</trackback:ping><description><![CDATA[<span class="bold">pku上的题目分类</span><br>
<br>
动态规划：<br>
1037 A decorative fence、1050 To the Max、1088 滑雪、1125 Stockbroker
Grapevine、1141 Brackets Sequence、1159 Palindrome、1160 Post Office、1163
The Triangle<br>
<br>
、1458 Common Subsequence、1579 Function Run Fun、1887 Testing the CATCHER、1953 World Cup Noise、2386 Lake Counting<br>
<br>
简单、模拟题：<br>
1001 Exponentiation 、1002 487-3279、1003 Hangover 、1701 Dissatisfying
Lift、2301 Beat the Spread!、2304 Combination Lock、2328 Guessing
Game、2403 Hay <br>
<br>
Points 、2406 Power Strings、2339 Rock, Scissors, Paper、2350 Above
Average、2218 Does This Make Me Look Fat?、2260 Error Correction、2262
Goldbach\'s <br>
<br>
Conjecture、2272 Bullseye、2136 Vertical Histogram、2174 Decoding
Task、2183 Bovine Math Geniuses、2000 Gold Coins、2014 Flow Layout、2051
Argus、2081 <br>
<br>
Calendar、1918 Ranking List、1922 Ride to School、1970 The Game、1972 Dice
Stacking、1974 The Happy Worm、1978 Hanafuda Shuffle、1979 Red and
Black、1617 <br>
<br>
Crypto Columns、1666 Candy Sharing Game、1674 Sorting by Swapping、1503
Integer Inquiry、1504 Adding Reversed Numbers、1528 Perfection、1546
Basically <br>
<br>
Speaking、1547 Clay Bully、1573 Robot Motion、1575 Easier Done Than
Said?、1581 A Contesting Decision、1590 Palindromes、1454 Factorial
Frequencies、1363 <br>
<br>
Rails、1218 THE DRUNK JAILER、1281 MANAGER、1132 Border、1028 Web Navigation、<br>
博弈类<br>
1067 取石子游戏、1740 A New Stone Game、2234 Matches Game、1082 Calendar Game 、2348 Euclid\'s Game、2413 How many Fibs?、2419 Forests<br>
初等数学<br>
1003 Hangover、1045 Bode Plot、1254 Hansel and Grethel、1269 Intersecting
Lines、1401 Factorial、1410 Intersection、2363 Blocks 、2365 Rope、2242 The <br>
<br>
Circumference of the Circle、2291 Rotten Ropes、2295 A DP Problem、2126
Factoring a Polynomial、2191 Mersenne Composite Numbers、2196 Specialized
Four-Digit <br>
<br>
Numbers、1914 Cramer\'s Rule、1835 宇航员、1799 Yeehaa!、1607 Deck、1244 Slots
of Fun、1269 Intersecting Lines、1299 Polar Explorer、1183 反正切函数的应用、<br>
<br>
图论及组合数学<br>
2421 Constructing Roads、2369 Permutations、2234 Matches Game、2243 Knight
Moves、2249 Binomial Showdown、2255 Tree Recovery、2084 Game of
Connections、1906 <br>
<br>
Three powers、1833 排列、1850 Code、1562 Oil Deposits、1496 Word Index、1306
Combinations、1125 Stockbroker Grapevine、1129 Channel Allocation、1146 ID
Codes<br>
<br>
、1095 Trees Made to order、找规律2247 Humble Numbers、2309 BST、2346 Lucky
tickets、2370 Democracy in danger、2365 Rope、2101 Honey and Milk Land <br>
2028 When Can We Meet?、2084 Game of Connections、1915 Knight Moves、1922
Ride to School、1941 The Sierpinski Fractal、1953 World Cup Noise、1958
Strange <br>
<br>
Towers of Hanoi、1969 Count on Canton、1806 Manhattan 2025、1809
Regetni、1844 Sum、1870 Bee Breeding、1702 Eva\'s Balance、1728 A flea on a
chessboard、1604 <br>
<br>
Just the Facts、1642 Stacking Cubes、1656 Counting Black、1657 Distance on
Chessboard、1662 CoIns、1663 Number Steps、1313 Booklet Printing、1316 Self
<br>
<br>
Numbers、1320 Street Numbers、1323 Game Prediction、1338 Ugly Numbers、1244
Slots of Fun、1250 Tanning Salon、1102 LC-Display、1147 Binary codes、1013 <br>
<br>
Counterfeit Dollar、<br>
---------------------------------------------------------------------------------------------------------------------------<br>
题目分类<br>
排序 1002（需要字符处理，排序用快排即可） 1007（稳定的排序） 2159（题意较难懂） 2231 2371（简单排序） 2388（顺序统计算法） 2418（二叉排序树）<br>
<br>
回溯搜索：1979（和迷宫类似） 1980（对剪枝要求较高）<br>
<br>
数学计算&nbsp;&nbsp;简单（或不值得做的题）：1003 1004 1005 1068 1326 1656 1657 1658 1663 1922
1978 2000 2013 2014 2017 2070 2101 2105 2140 2190 2272 2301 2405 2419<br>
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 中等：1006（中国剩余定理） 1323 1969 2015（解密码） 2081（预处理） 2085（找规律）<br>
难：&nbsp;&nbsp;1014 1037 1147 2082&nbsp;&nbsp;（这些是上课讲的）<br>
<br>
高精度计算：1001（高精度乘法） 2413(高精度加法，还有二分查找)<br>
<br>
历法：1008 2080 （这种题要小心）<br>
<br>
枚举：1054（剪枝要求较高） 1650 （小数的精度问题）<br>
<br>
数据结构的典型算法：1125(弗洛伊德算法) 2421（图的最小生成树）<br>
<br>
动态规划：1163（经典题）<br>
<br>
贪心：1328 1755（或用单纯形方法） 2054<br>
<br>
模拟： 1281 1928 2083 2141 2015<br>
<br>
递归： 1664<br>
字符串处理：2121 2403<br>
<br>
---------------------------------------------------------------------------------------------------------------------------<br>
有标准模型的：<br>
1125 1163 1183 1979 1185 1184 1187<br>
寻找新算法的：<br>
1014 1067 1147 1922 2082<br>
调节情绪用：<br>
1004 950 1218 1281 1928 1978 2000 2027<br>
<br>
---------------------------------------------------------------------------------------------------------------------------<br>
主流算法：<br>
1.搜索　//回溯<br>
2.DP（动态规划）　<br>
3.贪心　<br>
4.图论　//Dijkstra、最小生成树、网络流<br>
5.数论　//解模线性方程<br>
6.计算几何　//凸壳、同等安置矩形的并的面积与周长<br>
7.组合数学　//Polya定理<br>
8.模拟　<br>
9.数据结构　//并查集、堆<br>
10.博弈论　<br>
//表示举例<br>
<br>
非主流算法：<br>
1.送分题　<br>
2.构造　<br>
3.高精度　<br>
4.几何　<br>
5.排序　<br>
6.日期/时间处理　（这类题目相当多的）<br>
7.数学方法　<br>
8.枚举　<br>
9.递推　<br>
10.递归　<br>
11.分治　<br>
<br>
<br>
说明：<br>
显然&#8220;送分题&#8221;不是一种算法。但是ACM竞赛中经常有一些很简单很简单的题目，具体涉及内容繁杂，难以归类，干脆就管他们叫送分题。<br>
几何不同于计算几何，计算几何或者叫S计算几何，以Shamos在1975年发表的一篇论文为诞生标志。其实两者有很大的不同。<br>
<br>
部分题目分类统计：<br>
<br>
网络流：<br>
最大流：<br>
1087 a plug for UNIX<br>
1149 PIGS<br>
1273 drainage ditches<br>
1274 the perfect stall<br>
1325 machine schedule<br>
1459 power network<br>
2239 selecting courses<br>
最小费用最大流：<br>
2195 going home<br>
?2400 supervisor, supervisee<br>
<br>
压缩存储的DP<br>
1038 bugs integrated inc<br>
1185 炮兵阵地<br>
2430 lazy cow<br>
<br>
最长公共子串（LCS）：<br>
1080 human gene functions<br>
1159 palindrome<br>
1458 common subsequence<br>
2192 zipper<br>
<br>
凸包<br>
1113 wall<br>
2187 beauty contest<br>
<br>
<br>
---------------------------------------------------------------------------------------------------------------------------<br>
<br>
说明：递推算动归， 离散化算数据结构， 并查集算数据结构， 博弈算动归， 麻烦题一般都是不错的综合题， 最短路算图论，数据的有序化算排序<br>
<br>
麻烦题：<br>
1697, 1712, 1713, 1720, 1729, 1765, 1772, 1858, 1872, 1960, 1963, 2050, 2122, 2162, 2219, 2237, <br>
<br>
简单题目：<br>
1000, 1003, 1004, 1005, 1007, 1046, 1207, 1226, 1401, 1504, 1552, 1607,
1657, 1658, 1674, 1799, 1862, 1906, 1922, 1929, 1931, 1969, 1976, 2000,
2005, 2017, <br>
<br>
2027, 2070, 2101, 2105, 2109, 2116, 2136, 2160, 2190, 2232, 2234, 2275, 2301, 2350, 2363, 2389, 2393, 2413, 2419, <br>
推荐：<br>
1063, 1064, 1131, 1140, 1715, 2163, <br>
<br>
杂题：<br>
1014, 1218, 1316, 1455, 1517, 1547, 1580, 1604, 1663, 1678, 1749, 1804,
2013, 2014, 2056, 2059, 2100, 2188, 2189, 2218, 2229, 2249, 2290, 2302,
2304, 2309, <br>
<br>
2313, 2316, 2323, 2326, 2368, 2369, 2371, 2402, 2405, 2407, <br>
推荐：<br>
1146, 1147, 1148, 1171, 1389, 1433, 1468, 1519, 1631, 1646, 1672, 1681,
1700, 1701, 1705, 1728, 1735, 1736, 1752, 1754, 1755, 1769, 1781, 1787,
1796, 1797, <br>
<br>
1833, 1844, 1882, 1933, 1941, 1978, 2128, 2166, 2328, 2383, 2420, <br>
<br>
高精度：<br>
1001, 1220, 1405, 1503, <br>
<br>
排序：<br>
1002, 1318, 1877, 1928, 1971, 1974, 1990, 2001, 2002, 2092, 2379, 2388, 2418, <br>
推荐：<br>
1423, 1694, 1723, 1727, 1763, 1788, 1828, 1838, 1840, 2201, 2376, 2377, 2380, <br>
<br>
搜索<br>
容易：<br>
1128, 1166, 1176, 1231, 1256, 1270, 1321, 1543, 1606, 1664, 1731, 1742,
1745, 1847, 1915, 1950, 2038, 2157, 2182, 2183, 2381, 2386, 2426, <br>
不易：<br>
1024, 1054, 1117, 1167, 1708, 1746, 1775, 1878, 1903, 1966, 2046, 2197, 2349, <br>
推荐：<br>
1011, 1190, 1191, 1416, 1579, 1632, 1639, 1659, 1680, 1683, 1691, 1709,
1714, 1753, 1771, 1826, 1855, 1856, 1890, 1924, 1935, 1948, 1979, 1980,
2170, 2288, <br>
<br>
2331, 2339, 2340, <br>
<br>
数据结构<br>
容易：<br>
1182, 1656, 2021, 2023, 2051, 2153, 2227, 2236, 2247, 2352, 2395, <br>
不易：<br>
1145, 1177, 1195, 1227, 1661, 1834, <br>
推荐：<br>
1330, 1338, 1451, 1470, 1634, 1689, 1693, 1703, 1724, 1988, 2004, 2010, 2119, 2274, <br>
<br>
动态规划<br>
容易：<br>
1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 1189, 1208,
1276, 1322, 1414, 1456, 1458, 1609, 1644, 1664, 1690, 1699, 1740, 1742,
1887, 1926, <br>
<br>
1936, 1952, 1953, 1958, 1959, 1962, 1975, 1989, 2018, 2029, 2033, 2063,
2081, 2082, 2181, 2184, 2192, 2231, 2279, 2329, 2336, 2346, 2353, 2355,
2356, 2385, <br>
<br>
2392, 2424, <br>
不易：<br>
1019, 1037, 1080, 1112, 1141, 1170, 1192, 1239, 1655, 1695, 1707, 1733,
1737, 1837, 1850, 1920, 1934, 1937, 1964, 2039, 2138, 2151, 2161, 2178,
<br>
推荐：<br>
1015, 1635, 1636, 1671, 1682, 1692, 1704, 1717, 1722, 1726, 1732, 1770,
1821, 1853, 1949, 2019, 2127, 2176, 2228, 2287, 2342, 2374, 2378, 2384,
2411, <br>
<br>
字符串：<br>
1488, 1598, 1686, 1706, 1747, 1748, 1750, 1760, 1782, 1790, 1866, 1888,
1896, 1951, 2003, 2121, 2141, 2145, 2159, 2337, 2359, 2372, 2406, 2408,
<br>
<br>
贪心：<br>
1042, 1065, 1230, 1323, 1477, 1716, 1784, <br>
<br>
图论<br>
容易：<br>
1161, 1164, 1258, 1175, 1308, 1364, 1776, 1789, 1861, 1939, 1940, 1943, 2075, 2139, 2387, 2394, 2421, <br>
不易：<br>
1041, 1062, 1158, 1172, 1201, 1275, 1718, 1734, 1751, 1904, 1932, 2173, 2175, 2296, <br>
网络流：<br>
1087, 1273, 1698, 1815, 2195, <br>
匹配：<br>
1274, 1422, 1469, 1719, 2060, 2239, <br>
Euler：<br>
1237, 1637, 1394, 2230, <br>
推荐：<br>
2049, 2186, <br>
<br>
计算几何<br>
容易：<br>
1319, 1654, 1673, 1675, 1836, 2074, 2137, 2318, <br>
不易：<br>
1685, 1687, 1696, 1873, 1901, 2172, 2333, <br>
凸包：<br>
1113, 1228, 1794, 2007, 2187, <br>
<br>
模拟<br>
容易：<br>
1006, 1008, 1013, 1016, 1017, 1169, 1298, 1326, 1350, 1363, 1676, 1786, 1791, 1835, 1970, 2317, 2325, 2390, <br>
不易：<br>
1012, 1082, 1099, 1114, 1642, 1677, 1684, 1886, <br>
<br>
数学<br>
容易：<br>
1061, 1091, 1142, 1289, 1305, 1306, 1320, 1565, 1665, 1666, 1730, 1894,
1914, 2006, 2042, 2142, 2158, 2174, 2262, 2305, 2321, 2348, <br>
不易：<br>
1067, 1183, 1430, 1759, 1868, 1942, 2167, 2171, 2327, <br>
推荐：<br>
1423, 1450, 1640, 1702, 1710, 1721, 1761, 1830, 1930, 2140, <br>
<br>
---------------------------------------------------------------------------------------------------------------------------<br>
POJ部分题目分类<br>
算法入门（简单题）<br>
1000 1003 1004 1005 1006 1007 1015（学会dp） 1016 10171018 1042（dp） 1046（简单数学） 1054（简单的剪枝） 1062（dp） 1068<br>
1095 1113（凸包，但规模小，O(n^2)的也行）&nbsp;&nbsp;1125&nbsp;&nbsp;1127&nbsp;&nbsp;1152&nbsp;&nbsp;1154<br>
1183（用笔算算）&nbsp;&nbsp;1218 1221 1244 1281 1312 1313（找找规律）<br>
1315（学会搜索） 1321（同1315） 1323(dp)&nbsp;&nbsp;1326 1331 1491<br>
1493（找规律） 1503（高精度） 1504 1517 1519 1547 1552<br>
1563（考虑仔细一点，还要注意精度） 1650（不是好题） 1651（dp） 1656<br>
1657 1658 1663 1675（计算几何） 1681 1702（三进制运算） 1799<br>
1828 1862（简单数学） 1887 1906（实战好题） 1914 1915（宽搜）<br>
1928 1936 1978 1979 2000 2019（dp好题） 2027（垃圾题） 2028<br>
2078（不要重复搜索） 2080 2081 2083 2140 2141 2184（活用dp）<br>
2190 2192 2193 2196 2199 2209 2211&nbsp;&nbsp;2243 2248（搜索）<br>
2260 2261 2262 2291 2301 2304 2309（找规律） 2316 2317<br>
2318 2325 2355 2357 2363 2378（树的dp） 2381 2385 2393<br>
2394 2395 2413（高精度基础） 2418 2419<br>
<br>
经典<br>
1011（搜索好题） <br>
1012（学会打表）<br>
1013<br>
1019（它体现了很多此类问题的特点）<br>
1050（绝对经典的dp）<br>
1088（dp好题）<br>
1157（花店，经典的dp）<br>
1163（怎么经典的dp那么多呀？？？）<br>
1328（贪心）<br>
1458（最长公共子序列）<br>
1647（很好的真题，考临场分析准确和下手迅速）<br>
1654（学会多边形面积的三角形求法）<br>
1655（一类无根树的dp问题）<br>
1804（逆序对）<br>
2084（经典组合数学问题）<br>
2187（用凸包求最远点对，求出凸包后应该有O(N)的求法，可我就是调不出来）<br>
2195（二分图的最佳匹配）<br>
2242（计算几何经典）<br>
2295（等式处理）<br>
2353（dp，但要记录最佳路径）<br>
2354（立体解析几何）<br>
2362（搜索好题）<br>
2410（读懂题是关键）<br>
2411（经典dp）<br>
<br>
趣味<br>
1067（很难的数学，但仔细研究，是一片广阔的领域）<br>
1147（有O(n)的算法，需要思考）<br>
1240（直到一棵树的先序和后序遍历，那么有几种中序遍历呢？dp）<br>
1426（是数论吗？错，是图论！）<br>
1648（别用计算几何，用整点这个特点绕过精度的障碍吧）<br>
1833（找规律）<br>
1844（貌似dp或是搜索，其实是道有趣的数学题）<br>
1922（贪心，哈哈）<br>
2231<br>
2305（不需要高精度噢）<br>
2328（要仔细噢）<br>
2356（数论知识）<br>
2359（约瑟夫问题变种）<br>
2392（有趣的问题）<br>
<br>
很繁的题<br>
1001<br>
1008<br>
1087（构图很烦，还有二分图的最大匹配）<br>
1128（USACO）<br>
1245<br>
1329<br>
1550（考的是读题和理解能力）<br>
1649（dp）<br>
2200（字符串处理+枚举）<br>
2358（枚举和避免重复都很烦）<br>
2361（仔细仔细再仔细）<br>
<br>
难题<br>
1014（数学证明比较难，但有那种想法更重要）<br>
1037（比较难的dp）<br>
1405（高精度算法也分有等级之分，不断改进吧）<br>
2002（不知道有没有比O(n^2*logn)更有的算法？）<br>
2054（极难，很强的思考能力）<br>
2085（组合数学）<br>
2414（dp，但要剪枝）<br>
2415（搜索）<br>
2423（计算几何+统计）<br>
<br>
多解题<br>
1002（可以用排序，也可以用统计的方法）<br>
1338（搜索和dp都可以）<br>
1664（搜索和dp都练一练吧）<br>
2082（这可是我讲的题噢）<br>
2352（桶排和二叉树都行）<br>
<br>
---------------------------------------------------------------------------------------------------------------------------<br>
Instruction:<br>
If there is an * after a problem ID, it means a simple note followed below.<br>
For freshman:<br>
1001 1002 1007 1008 1012 1016 1068 1163 1218(*) <br>
1281 1316 1326 1411 1552 1647 1650 1658 1659 1663 <br>
1666 1928 1936 2013 2014 2017 2080 2083 2105 2136 <br>
2141 2163 2242 2244 2328 2386 2403 2405 2413 2419<br>
A little skill needed:<br>
1013 1026 1029(similar to 1013) 1147 1152 1405 1649 1657 1922<br>
2081 2085 2140 2159 2247 2309 2402<br>
Math problem:<br>
1006 1061 1095 1183 1700(*) 1844 1862 2084(*) 2232 2234(*)<br>
Search:<br>
1011(*) 1129 2078(*) 2362(similar to 1011)<br>
Graph:<br>
1062 1094 1125 1128 1130 1655 1661 1674(*) 1909 2049 2195(*) 2395(*)<br>
2421<br>
DP problems:<br>
1029 1050 1080 1088 1651 1664 1742(*) 2181 2192 2392(similar to 1742)<br>
2397 2411(*)<br>
Greedy:<br>
1017(*) 1065 1083(*) 1089 1323 1328 1505(*) 1828 2082(*) 2393<br>
Data Structure :<br>
1988(*) 2051(*) 2182(*) 2236(*) 2424<br>
Others:<br>
1150(*) 1654(*) 1833 1835 2299(*) 2406(*) 2407<br>
A bit complicated:<br>
1021(*) 1054 1863(*) 2015<br>
Great Challenging<br>
1014(*)<br>
<br>
Note:<br>
1011: 很经典的剪支<br>
1014: 难在数学上<br>
1017: 严格的数学证明貌似不容易<br>
1021: 有点繁,考察对图形进行各种旋转的处理<br>
1083: 巧妙的思考角度<br>
1150: 分奇偶讨论,lg(n)算法<br>
1218: 三行就够了,虽然简单,但也有优劣之别<br>
1505: 二分加贪心<br>
1654: 做法也许很多吧,本人用有向面积做的<br>
1674: 计算圈的个数(算是graph 吧)<br>
1700: 数学证明不容易<br>
1742: O(m*n)的算法<br>
1863: 要耐心地慢慢写&#8230;^_^<br>
1988: 并查集<br>
2051: 堆<br>
2078: 不难，但剪支可以做到很好<br>
2082::O(n),你想到了吗？<br>
2084: 卡特兰数<br>
2182: 线段树<br>
2195: 最小费用最大流<br>
2234: 经典博弈算法<br>
2236: 并查集<br>
2299: 二分思想<br>
2395: Kruskal 最小生成树的拓展<br>
2406: KMP<br>
2411: 用二进制串来表示状态<br>
<br>
---------------------------------------------------------------------------------------------------------------------------<br>
Judge Online<br>
基础题:<br>
1000,1003,1004,1005,1008,1012,1013,1016,1019,1022<br>
1026,1028,1029,1035,1046,1247,1298,1316,1326,1401<br>
1504,1547,1552,1647,1648,1649,1650,1651,1652,1653<br>
1657,1658,1663,1750,1754,1922,1928,1969,2027,2080<br>
2081,2085,2105,2136,2190,2210,2249,2272,2273,2275<br>
2291,2295,2301,2304,2316,2328,2334,2381,2390<br>
基本数据结构:<br>
堆:<br>
1442<br>
排序分治:<br>
1002,1007,1400,2084,2282,2299,2318,2379,2388<br>
递归枚举搜索:<br>
1010,1011,1018,1020,1054,1062,1256,1321,1363,1501<br>
1650,1659,1664,1753,2078,2083,2303,2310,2329<br>
动态规划:<br>
1015,1163,1404,1651,1661,1742,2292,2385,2392<br>
贪心:<br>
1017,2054,2336,2393<br>
图论网络流:<br>
1021,1024,1027,1088,1125,1130,1154,1502,1751,2309<br>
2312,2386,2387,2394,2395<br>
数论:<br>
1006,1014,1023,1061,1152,1183,1730,2262<br>
计算几何:<br>
1654,2179,2284<br>
模拟题:<br>
1049,1051,1234,1207,1218,1281,2271,2302,2317,2339<br>
高精度数值计算:<br>
1001,1131,1503,2305,2325,2389<br>
概率统计:<br>
1037,1050<br>
其他:<br>
1009,1147,2082<br>
<br>
---------------------------------------------------------------------------------------------------------------------------<br>
POJ已完成题目小结<br>
基础题（比较容易，应该很快做出来的）: <br>
1000,1003,1004,1005,1008,1012,1013,1016,1019,1026,1046,1102,1107,1247,1298,1316,1326,<br>
1519,1543,1547,1552,1565,1581,1647,1649,1648,1651,1652,1657,1658,1731,1799,1922,1928,<br>
1969,2000,2013,2014,2017,2027,2070,2080,2081,2105,2136,2140,2041,2159,2190,2301,2350,<br>
2388,2389,2390<br>
数据结构（包括最短路，最小生成树等）:2421,2092<br>
<br>
排序分治: 1002,1007,2388<br>
<br>
递归枚举搜索（有些题目还是比较难编的）: 1054,2083,1318, 1321,1363,1659,1664,1062, 1190,1831,2386<br>
博弈论1067,<br>
构造（比较难想出来的） 1091, 1147<br>
动态规划（有些很基础的，但也有很难的哦）: 1163, 1014, 1037, 1062, 1088, 1190<br>
贪心（仔细想想还是能够想到的）: 1017, 1042,1328, 1659，2092<br>
图论：1125<br>
数论（想啊想）: 1006,1014,1061,1953<br>
计算几何: 1654<br>
模拟题（有些模拟题那个难编阿）: 1207,1218,1281,1323,1350,1455,1928，2051,2424<br>
高精度数值计算（算是基础题）: 1001,1131,1405,1517,1604,2389<br>
密码题里面一道可以的：2015<br>
<br>
---------------------------------------------------------------------------------------------------------------------------<br>
POJ已完成题目小结<br>
（截至2005年4月22日）<br>
<br>
归类：<br>
分类原则：以算法核心指向为主<br>
算法<br>
题目<br>
枚举<br>
1012 1046 1387 1411 2245 2326 2363 2381 <br>
搜索、回溯、遍历<br>
1010 1011 1022 1054 1111 1118 1129 1190 1562 1564 1573 1655 2078 2184 2225 2243 2312 2362 2378 2386 <br>
动态规划<br>
1015 1018 1050 1088 1159 1163 1221 1322 1458 1579 1651 1664 1742 1745 1953 2033 2084 2229 2385 2392 2393 <br>
图论（不含图遍历）<br>
1125 1128 1130 2320 2387 2394 2395<br>
贪心<br>
1017 1328 1862 1922 2054 2209 2313 2325 2370 <br>
计算几何<br>
1648 1654 1927 2007 2098 2208 2242 2276 2318 <br>
数论<br>
1061 1320 1597 1808 1811 1845 <br>
其他数学、历法<br>
1005 1006 1008 1032 1067 1152 1183 1209 1401 1423 1491 1517 1528 1543
1707 1799 1844 1905 1914 1942 2080 2126 2140 2190 2210 2234 2249 2299
2321 2348 2354 <br>
<br>
2365 <br>
任意精度运算、数字游戏<br>
1001 1023 1047 1060 1079 1131 1140 1142 1207 1220 1284 1289 1306 1316
1338 1405 1454 1503 1504 1519 1565 1650 1969 2000 2006 2081 2247 2262
2305 2316 2389 <br>
基础算法、数据结构<br>
1002 1007 1028 1281 1308 2092 2104 2106 2340 2352 2366 2371 <br>
字符串处理<br>
1016 1051 1126 1318 1572 1917 1936 2039 2083 2136 2271 2317 2330 <br>
人工逻辑<br>
1013<br>
机械模拟、语言解析器<br>
1049 1600 1684 1928 2050 2339 2383<br>
其他题目<br>
1014 1026 1045 1083 1102 1146 1477 1647 1656 1657 1660 1926 2018 2082 2231 2309 2359 2369 2380 <br>
构造<br>
1147 1256 1426 1659 1833 1898 1906 2015 2085 2144 2201 2319 2356 <br>
无聊题目<br>
1000 1003 1004 1218 1298 1326 1552 1658 1665 2013 2017 2027 2105 2109 2272 2301 2328 2350 2388 2390 <br>
总计：228题<br>
---------------------------------------------------------------------------------------------------------------------------<br>
模拟题：<br>
1002 1004 1005 1008 1016 1326 1928 2136 2424<br>
<br>
高精度：<br>
1001 <br>
<br>
枚举：<br>
1012 1013<br>
<br>
贪心：<br>
1017 1922<br>
<br>
循环：<br>
1026<br>
<br>
动态规划：<br>
1163<br>
<br>
递归：<br>
1664<br>
<br>
最小生成树：<br>
2421<br>
<br>
其他：<br>
1000 1147 1657 1658 2082<br>
---------------------------------------------------------------------------------------------------------------------------<br>
<br>
Judge On line<br>
本学期刚开始做，不是很多，分得较细！<br>
一、按类型<br>
基础题:<br>
1000,1003,1004,1005，2013，2017<br>
模拟题:<br>
1281 1922 1928 <br>
2080 （细心）<br>
排序分治:<br>
1002 <br>
动态规划:<br>
1037&nbsp;&nbsp;（大规模） <br>
2084 （做高精度）<br>
贪心:<br>
2054<br>
数论:<br>
1001 整数运算（作高精度）<br>
1014 集合划分，与分治<br>
1147 1163 2081 2085数列问题<br>
几何有关的题目：<br>
1054 解析几何+搜索<br>
2014 <br>
2016计算几何<br>
2082集合的合并，运算（几何角度）<br>
2083 分形（纯数学）<br>
图：<br>
1125 <br>
利用题目所给信息来推演：<br>
2015<br>
二、按难易<br>
简单题<br>
最基础的适应POJ的习题：1000 1003 1004 1005 2013 2017<br>
需要根据情景稍微动下脑筋的习题：1922<br>
需要对语言有很深刻的了解，锻炼基本功的：1002 1281 2014 2081<br>
要求初步熟练算法的习题：1928 <br>
<br>
中档题：<br>
锻炼细心考虑问题全面的习题：1001 2015 2080 <br>
要求熟练算法的习题：1054 1163 2084 <br>
<br>
<br>
难题：<br>
对数学要求很高的题目：2083 2085<br>
对算法要求很高的题目：1125 2054 <br>
对综合能力要求很高的题目：1037 2016 2082 <br>
技巧性高的题目：1147<br>
锻炼英文读题的题目：2015 2082<br>
<br>
三、需要有很强的判断力的题目：<br>
判断高精度： 2084<br>
判断耗时：1002<br>
判断变量类型：1001<br>
要求会寻找题目以外的信息：2080<img src ="http://www.cppblog.com/koson/aggbug/109137.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/koson/" target="_blank">koson</a> 2010-03-07 19:57 <a href="http://www.cppblog.com/koson/archive/2010/03/07/109137.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>POJ 1837</title><link>http://www.cppblog.com/koson/archive/2009/12/01/102330.html</link><dc:creator>koson</dc:creator><author>koson</author><pubDate>Tue, 01 Dec 2009 07:16:00 GMT</pubDate><guid>http://www.cppblog.com/koson/archive/2009/12/01/102330.html</guid><wfw:comment>http://www.cppblog.com/koson/comments/102330.html</wfw:comment><comments>http://www.cppblog.com/koson/archive/2009/12/01/102330.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/koson/comments/commentRss/102330.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/koson/services/trackbacks/102330.html</trackback:ping><description><![CDATA[背包问题变形，定义数组，dp[21][4000+4000]，dp[i][j]表示挂了i个砝码时力矩和为j的方法数，因为力矩可能为负，所以加上4000的位移量，这样，最后 dp[C][4000]即为所求的结果。状态转移方程为: dp[1][4000+c[k]*g[1]]=1，k=1,,, C,挂一个砝码时进行初始化; 对于i=2,,,G,&nbsp; dp[i][j]+=dp[i-1][j- c[k]*g[i]],&nbsp; k=1,,,,C.。
<img src ="http://www.cppblog.com/koson/aggbug/102330.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/koson/" target="_blank">koson</a> 2009-12-01 15:16 <a href="http://www.cppblog.com/koson/archive/2009/12/01/102330.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>POJ 3007</title><link>http://www.cppblog.com/koson/archive/2009/11/26/101968.html</link><dc:creator>koson</dc:creator><author>koson</author><pubDate>Thu, 26 Nov 2009 06:23:00 GMT</pubDate><guid>http://www.cppblog.com/koson/archive/2009/11/26/101968.html</guid><wfw:comment>http://www.cppblog.com/koson/comments/101968.html</wfw:comment><comments>http://www.cppblog.com/koson/archive/2009/11/26/101968.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/koson/comments/commentRss/101968.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/koson/services/trackbacks/101968.html</trackback:ping><description><![CDATA[简单枚举，每次分八种情况。 使用stl一直TLE，用hash过了。 一开始用next_permutation列出所有排列然后判断此排列是否属于所求的值，后来发现next_permutation的复杂度为o(N!)，所以一直TLE。
<img src ="http://www.cppblog.com/koson/aggbug/101968.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/koson/" target="_blank">koson</a> 2009-11-26 14:23 <a href="http://www.cppblog.com/koson/archive/2009/11/26/101968.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ZOJ 2050</title><link>http://www.cppblog.com/koson/archive/2009/11/25/101909.html</link><dc:creator>koson</dc:creator><author>koson</author><pubDate>Wed, 25 Nov 2009 07:57:00 GMT</pubDate><guid>http://www.cppblog.com/koson/archive/2009/11/25/101909.html</guid><wfw:comment>http://www.cppblog.com/koson/comments/101909.html</wfw:comment><comments>http://www.cppblog.com/koson/archive/2009/11/25/101909.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/koson/comments/commentRss/101909.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/koson/services/trackbacks/101909.html</trackback:ping><description><![CDATA[基础BFS题，使用一个32位的int的16位来存储状态，如果是b，则对应位置为1，否则为0。状态空间最多有2^16-1=65535个状态，实际剪枝后去掉了相当多的冗余状态。这题输入包含了空行，使用scanf(" ")来获取清除空行，因为这个贡献了几个presetation error。
<img src ="http://www.cppblog.com/koson/aggbug/101909.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/koson/" target="_blank">koson</a> 2009-11-25 15:57 <a href="http://www.cppblog.com/koson/archive/2009/11/25/101909.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>poj 1157</title><link>http://www.cppblog.com/koson/archive/2009/11/17/101239.html</link><dc:creator>koson</dc:creator><author>koson</author><pubDate>Tue, 17 Nov 2009 12:42:00 GMT</pubDate><guid>http://www.cppblog.com/koson/archive/2009/11/17/101239.html</guid><wfw:comment>http://www.cppblog.com/koson/comments/101239.html</wfw:comment><comments>http://www.cppblog.com/koson/archive/2009/11/17/101239.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/koson/comments/commentRss/101239.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/koson/services/trackbacks/101239.html</trackback:ping><description><![CDATA[dp 设r[i][j]为i朵花放在j个花瓶的最大价值<br>初始化&nbsp; r[0][j]=0,j =1,2,...V<br>r[i][i]=r[i-1][i-1]+A[i][i]; i=1,2,...F<br>DP状态转移方程:&nbsp; i&gt;=1,2,...F, j&gt;=i+1,i+2,...V &nbsp;&nbsp; r[i][j]=max{ r[i][j-1], r[i-1][j-1]+A[i][j] };<br>r[F][V]即为所求结果
<img src ="http://www.cppblog.com/koson/aggbug/101239.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/koson/" target="_blank">koson</a> 2009-11-17 20:42 <a href="http://www.cppblog.com/koson/archive/2009/11/17/101239.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>zoj 1082</title><link>http://www.cppblog.com/koson/archive/2009/11/17/101213.html</link><dc:creator>koson</dc:creator><author>koson</author><pubDate>Tue, 17 Nov 2009 08:37:00 GMT</pubDate><guid>http://www.cppblog.com/koson/archive/2009/11/17/101213.html</guid><wfw:comment>http://www.cppblog.com/koson/comments/101213.html</wfw:comment><comments>http://www.cppblog.com/koson/archive/2009/11/17/101213.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/koson/comments/commentRss/101213.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/koson/services/trackbacks/101213.html</trackback:ping><description><![CDATA[<p>图论题<br>用floyd求出所有点对之前的最短距离，遍历每个点作为出发点，它与所有其它点之间的最长距离即为当前出发点出发所需的时间，再取出所有出发点的时间的最小值即为所求。注意当考虑某个出发点时，如果存在某个点达不到，则这种情况直接丢弃。另外还需考虑图不连通的情况。</p>
<img src ="http://www.cppblog.com/koson/aggbug/101213.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/koson/" target="_blank">koson</a> 2009-11-17 16:37 <a href="http://www.cppblog.com/koson/archive/2009/11/17/101213.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ZOJ 1029 moving tables</title><link>http://www.cppblog.com/koson/archive/2009/11/13/100867.html</link><dc:creator>koson</dc:creator><author>koson</author><pubDate>Fri, 13 Nov 2009 05:51:00 GMT</pubDate><guid>http://www.cppblog.com/koson/archive/2009/11/13/100867.html</guid><wfw:comment>http://www.cppblog.com/koson/comments/100867.html</wfw:comment><comments>http://www.cppblog.com/koson/archive/2009/11/13/100867.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/koson/comments/commentRss/100867.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/koson/services/trackbacks/100867.html</trackback:ping><description><![CDATA[<p>枚举所有移动，对当前移动，初始化移动次数为1，保存起始点和目标点；然后判断所有的移动（不包含当前移动），如果移动区间跟当前移动有交叉，则移动次数加1，并且更新起始点和目标点。最后取出所有移动次数最大的一个。复杂度为o(n^2)。题目n的规模为200。</p>
<img src ="http://www.cppblog.com/koson/aggbug/100867.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/koson/" target="_blank">koson</a> 2009-11-13 13:51 <a href="http://www.cppblog.com/koson/archive/2009/11/13/100867.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>