<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>碧云涛小屋 &#187; programming</title>
	<atom:link href="http://blog.axqd.net/tags/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.axqd.net</link>
	<description>by aXqd</description>
	<lastBuildDate>Tue, 09 Aug 2011 16:12:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
	<atom:link rel='hub' href='http://blog.axqd.net/?pushpress=hub'/>
		<item>
		<title>Google Code Jam 2009 (Practise)</title>
		<link>http://blog.axqd.net/2009/08/30/google-code-jam-2009-practise/</link>
		<comments>http://blog.axqd.net/2009/08/30/google-code-jam-2009-practise/#comments</comments>
		<pubDate>Sun, 30 Aug 2009 04:41:34 +0000</pubDate>
		<dc:creator>axqd</dc:creator>
				<category><![CDATA[挨踢技术]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[google code jam]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://blog.axqd.net/?p=700</guid>
		<description><![CDATA[去年做了做Google Code Jam的入围题，挺好玩的。今年早早的就收到了邮件，并且还附上了四道练习题。 1. [74%/80%] Alien Number：给定源语言以及目标语言，要求翻译一个数字。 这题按最自然的思路就行了。为方便起见，把源数字先转换成十进制，然后再用和十进制转二进制相同的辗转相除法，求得目标数字的表示。 2. [80%/84%] Always Turn Left：给定总是左转的规则及实际路线，要求实际的迷宫。 如果你身陷迷宫，“总是左转”的规则，或者说“手不离墙，摸着墙走”的规则，兴许能救你一命。 其实，这道题中，我们能得到的所有讯息，都在来回走的路径里面。所以只要跟着路径实际来回走一遍，并沿路，总结迷宫信息，最后得到的便是整个迷宫。 对于左右转及方向的表示，一堆if-else，时空都坏；归纳到一个表里面查表，空间效率也不高；其实就四个方向，如果NESW分别表示为0123的话，简单的加减取模，就能实现左右转了。至于walk through的坐标处理，选择一个简单的闭包最为理想。 另外，在处理路径的时候，维护一个x、y坐标的最大、最小值，以便于最后输出迷宫。 在输出迷宫的时候，不用先存储那张转换表，而直接把YES当成1，NO当成0，作为4位的二进制数，再表示为16进制，刚好就是那张表。 ==== 从题目前括号里表示的人们的成功率上来看，前两题比较简单，后两题比较困难 ==== 3. [68%/49%] Egg Drop：给定某个可解扔蛋问题的三个参量，在保持可解的情况下，求每个参量的极大值或极小值 这道题有很自然的思路，那便是Fmax的递推式： 设想现在在第 i 层扔蛋，那么第 i 层扔了，就能确定状态，因此本身算一层 ( 1 )； 如果蛋没碎，往上验，最多还能验F( D – 1, B )层[ 因为第 i 层扔了一次，D减1；蛋没碎，B不变 ]； 如果蛋碎了，往下验，最多还能验F( D – 1, B – 1 )层[ 因为第 i [...]<table class="wumii-related-items" cellspacing="0" cellpadding="2" border="0" width="100%" style="clear: both;">
    
    <tr>
        <td ><b><font size="-1"  style="display: block !important; padding: 20px 0 5px !important;">无觅猜您也喜欢：</font></b></td>
    </tr>
    
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.axqd.net%2F2011%2F05%2F08%2Fgoogle-code-jam-2011-qualification%2F&from=http%3A%2F%2Fblog.axqd.net%2F2009%2F08%2F30%2Fgoogle-code-jam-2009-practise%2F">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">Google Code Jam 2011 (Qualification)</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.axqd.net%2F2009%2F09%2F04%2Fgoogle-code-jam-2009-qualification%2F&from=http%3A%2F%2Fblog.axqd.net%2F2009%2F08%2F30%2Fgoogle-code-jam-2009-practise%2F">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">Google Code Jam 2009 (Qualification)</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.axqd.net%2F2008%2F07%2F18%2Fgoogle-code-jam-2008%2F&from=http%3A%2F%2Fblog.axqd.net%2F2009%2F08%2F30%2Fgoogle-code-jam-2009-practise%2F">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">Google Code Jam 2008</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.axqd.net%2F2010%2F02%2F11%2Fgoogle-buzz-in-chengdu%2F&from=http%3A%2F%2Fblog.axqd.net%2F2009%2F08%2F30%2Fgoogle-code-jam-2009-practise%2F">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">Google Buzz in Chengdu</font>
                    </a>
                </td>
            </tr>
    
    <tr>
        <td  align="right">
            <a style="text-decoration: none !important;" href="http://www.wumii.com/widget/relatedItems.htm" target="_blank" title="无觅相关文章插件">
                <font size="-1" color="#bbbbbb" style="display: block !important; font-family: arial !important; padding: 5px 0 !important; font-size: 12px !important; color: #bbb !important;">无觅</font>
            </a>
        </td>
    </tr>
</table>]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.axqd.net/2008/07/18/google-code-jam-2008/" target="_blank">去年做了做Google Code Jam的入围题</a>，挺好玩的。今年早早的就收到了邮件，并且还附上了四道练习题。</p>
<p>1. [74%/80%] Alien Number：给定源语言以及目标语言，要求翻译一个数字。</p>
<p>这题按最自然的思路就行了。为方便起见，把源数字先转换成十进制，然后再用和十进制转二进制相同的辗转相除法，求得目标数字的表示。</p>
<p>2. [80%/84%] Always Turn Left：给定总是左转的规则及实际路线，要求实际的迷宫。</p>
<p>如果你身陷迷宫，“总是左转”的规则，或者说“手不离墙，摸着墙走”的规则，兴许能救你一命。</p>
<p>其实，这道题中，我们能得到的所有讯息，都在来回走的路径里面。所以只要跟着路径实际来回走一遍，并沿路，总结迷宫信息，最后得到的便是整个迷宫。</p>
<p>对于左右转及方向的表示，一堆if-else，时空都坏；归纳到一个表里面查表，空间效率也不高；其实就四个方向，如果NESW分别表示为0123的话，简单的加减取模，就能实现左右转了。至于walk through的坐标处理，选择一个简单的闭包最为理想。</p>
<p>另外，在处理路径的时候，维护一个x、y坐标的最大、最小值，以便于最后输出迷宫。</p>
<p>在输出迷宫的时候，不用先存储那张转换表，而直接把YES当成1，NO当成0，作为4位的二进制数，再表示为16进制，刚好就是那张表。</p>
<p>==== 从题目前括号里表示的人们的成功率上来看，前两题比较简单，后两题比较困难 ====</p>
<p>3. [68%/49%] Egg Drop：给定某个可解扔蛋问题的三个参量，在保持可解的情况下，求每个参量的极大值或极小值</p>
<p>这道题有很自然的思路，那便是Fmax的递推式：</p>
<p>设想现在在第 i 层扔蛋，那么第 i 层扔了，就能确定状态，因此本身算一层 ( 1 )；<br />
如果蛋没碎，往上验，最多还能验F( D – 1, B )层[ 因为第 i 层扔了一次，D减1；蛋没碎，B不变 ]；<br />
如果蛋碎了，往下验，最多还能验F( D – 1, B – 1 )层[ 因为第 i 层扔了一次，D减1；蛋碎了，B也减1 ]。</p>
<p>由于每次验证，蛋只能处于碎或不碎状态中的一种，所以二者并不互相影响。故：</p>
<p>F(D, B) = 1 + F( D – 1, B ) + F( D – 1, B – 1 )</p>
<p>接下来如何计算这个递推式，是个问题。如果这个问题解决了，那么要找到最小的D和B，直接查表既可。</p>
<p>容易看出，递推式中有大量重复的子问题，动态规划应该效果不错。不过，我们还是先来看看数据膨胀速度如何：</p>
<p>[B]<br />
1 3 7 15<br />
1 3 7 14<br />
1 3 6 10<br />
1 2 3 4   [D]</p>
<p>左上部分不用计算，就是对角线上的数字，因为能打碎的数量，如果超过总的实验次数，多出来的这部分就没意义了。故：</p>
<p>F( D, B ) = F( D, D ) if( B &gt; D )</p>
<p>直接观察对角线上的数字，容易看出，对角线上的数字为 2^D &#8211; 1。</p>
<p>即使没有看出来，也可以推出来。只用由F(D, B)的递推式和上面B&gt;D的性质，得出递推式 A(n)=2A(n-1)+1，并求解既可。</p>
<p>由此可见，这张表的数字膨胀速度相当快(2^n)。因此，我们得充分利用一个很不起眼的条件，那便是F有2^32的大小限制。</p>
<p>B再大，在应用上面B&gt;D的性质后，也不会超过32。整张表的纵向高度就限制得很小了。</p>
<p>但整张表的横向高度依然可以很大，比如F( 2000000000, 1 )，这种情况即使动态规划会很吃苦头。</p>
<p>观察每一列，都是从 D ~ (2 ^ D – 1)，之间的每个数的差值，刚好是杨辉三角。</p>
<p>1&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;0<br />
1          1&#8212;&#8212;&#8212;&#8212;-1<br />
1          2       1&#8212;&#8212;&#8212;&#8211;2<br />
1        3         3        1&#8212;&#8212;-3<br />
1        4         6        4        1&#8212;-4<br />
0Cr4 1Cr4 2Cr4 3Cr4 4Cr4</p>
<p>15 – 1 = 14<br />
14 – 4 = 10<br />
10 – 6 = 4</p>
<p>所以，从D开始往上累加各个组合数，既可得出某一位的值。而这个累加过程，一旦大于2 ^ 32便可退出。</p>
<p>算出了Fmax，Bmin可以直接挨个找，因为表的纵向高度有限。而Dmin，则需要一个简单的折半查找，以应对F( 2000000000, 1 )类似的情况。</p>
<p>4. [64%/31%] Shopping Plan：给定商店、油费和要买的东西，求最低花费</p>
<p>31%的大数据集通过率，可见这道题的时间或者空间复杂度比较高。</p>
<p>这道题乍看之下，容易让人想起Dijkstra算法[<a href="http://www.people.com.cn/GB/it/48/298/20020917/824179.html" target="_blank">王选貌似还谈论过Dijkstra这个人</a>]。但我很难想到简单的一个数，来指征当前选择的优劣。因为要考虑的因素，实在很多，离家的远近、当前购买物的价格、路径、还有买了是否需要立刻回家等等。</p>
<p>另外，最优子结构的寻找，也颇为困难。因为容易理解，买abcd的最佳路径不一定包括买abc的最优路径。</p>
<p>在这种情况下，我们不得不增强条件。我们以a. 从某个商店出发，b. 买完某些商品，c. 并且当前是否需要回家为基准计算最小值。</p>
<p>这里面依然可以看出，有大量的重复子问题，可以动态规划。</p>
<p>我们遍历当前商店里能买到的并且当前需要购买的商品，买之，然后再遍历所有商店作为下一个商店，并且考虑当前买的商品是否需要立刻放回家。如果已经买完了，则立刻回家。</p>
<p>这里有一个想法很诱惑，那便是走过的商店便不需要再走。因为非perishable的商品始终能顺带带走，perishable的商品始终要立刻回家，也不需要第二次光顾来买。所以，如果以空间换时间，在过程中排除掉某些商店，效果应该不错。但再仔细想想就会发现，这里的空间开销很大，即使用bit set，也需要2 ^50。而所换来的时间并不多，因为我们依然得处理这个比特集。</p>
<p>这样实现的一个perl脚本的性能如下：</p>
<p>[小数据集 100 cases] &#8211; 工作很好</p>
<p>real  0m0.297s<br />
user 0m0.260s<br />
sys  0m0.040s</p>
<p>[大数据集 20 cases] &#8211; 严重超时</p>
<p>real   35m4.110s<br />
user  34m20.661s<br />
sys    0m42.387s</p>
<p>0.297s已经是对perl脚本做性能调校之后的结果，所以不更改算法或者更改编程语言，很难有所提高了。这里我选择了后面一种方式，用纯C实现了一个相同的算法：</p>
<p>由于perl处理文本始终还是方便很多，所以先用preprocess.pl脚本把input文本解析为利于C解析的格式。[这里是每行一个数字，并处理掉商品名称]</p>
<p>然后用纯C的程序读入处理后的文本，并输出，[ $gcc –O3 run.c –lm ]下面是一些性能数据：</p>
<p>[小数据集 100 cases]</p>
<p>real    0m0.223s<br />
user   0m0.220s<br />
sys    0m0.004s</p>
<p>完全没有缓存的版本，已然比perl的要好，接下来为算路费的函数添加缓存：</p>
<p>real    0m0.128s<br />
user   0m0.124s<br />
sys    0m0.004s</p>
<p>再为递归函数添加缓存：</p>
<p>real    0m0.004s<br />
user   0m0.004s<br />
sys    0m0.000s</p>
<p>这里就已经相当理想了，可以预见大数据集性能也不会差。</p>
<p>[大数据集 20 cases]</p>
<p>real    0m16.551s<br />
user   0m16.501s<br />
sys    0m0.048s</p>
<p>16s，算是很完美的性能了。同样的算法，动态脚本和纯C还是没法比啊，呵呵。即使在极限情况，50个商店，15个待购商品的case，也能在0m12.260s内解决。</p>
<p><a href="http://blog.axqd.net/wp-content/uploads/2009/08/GCJ-2009-Practise.zip">GCJ 2009 Practise Solution Download</a></p>
<table class="wumii-related-items" cellspacing="0" cellpadding="2" border="0" width="100%" style="clear: both;">
    
    <tr>
        <td ><b><font size="-1"  style="display: block !important; padding: 20px 0 5px !important;">无觅猜您也喜欢：</font></b></td>
    </tr>
    
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.axqd.net%2F2011%2F05%2F08%2Fgoogle-code-jam-2011-qualification%2F&from=http%3A%2F%2Fblog.axqd.net%2F2009%2F08%2F30%2Fgoogle-code-jam-2009-practise%2F">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">Google Code Jam 2011 (Qualification)</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.axqd.net%2F2009%2F09%2F04%2Fgoogle-code-jam-2009-qualification%2F&from=http%3A%2F%2Fblog.axqd.net%2F2009%2F08%2F30%2Fgoogle-code-jam-2009-practise%2F">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">Google Code Jam 2009 (Qualification)</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.axqd.net%2F2008%2F07%2F18%2Fgoogle-code-jam-2008%2F&from=http%3A%2F%2Fblog.axqd.net%2F2009%2F08%2F30%2Fgoogle-code-jam-2009-practise%2F">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">Google Code Jam 2008</font>
                    </a>
                </td>
            </tr>
            <tr>
                <td style="margin: 0 !important; padding: 0 !important; line-height: 20px !important;">
                    <img border="0" src="http://static.wumii.com/images/widget/widget_solidPoint.gif">
                    <a target="_blank" style="text-decoration: none !important;" href="http://app.wumii.com/ext/redirect.htm?url=http%3A%2F%2Fblog.axqd.net%2F2010%2F02%2F11%2Fgoogle-buzz-in-chengdu%2F&from=http%3A%2F%2Fblog.axqd.net%2F2009%2F08%2F30%2Fgoogle-code-jam-2009-practise%2F">
                        <font size="-1" color="#333333" style="line-height: 1.65em; font-size: 12px !important;">Google Buzz in Chengdu</font>
                    </a>
                </td>
            </tr>
    
    <tr>
        <td  align="right">
            <a style="text-decoration: none !important;" href="http://www.wumii.com/widget/relatedItems.htm" target="_blank" title="无觅相关文章插件">
                <font size="-1" color="#bbbbbb" style="display: block !important; font-family: arial !important; padding: 5px 0 !important; font-size: 12px !important; color: #bbb !important;">无觅</font>
            </a>
        </td>
    </tr>
</table>]]></content:encoded>
			<wfw:commentRss>http://blog.axqd.net/2009/08/30/google-code-jam-2009-practise/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

