<?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>JavaChen Blog &#187; C/Algorithm</title>
	<atom:link href="http://www.javachen.com/category/algorithm/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.javachen.com</link>
	<description>Just some random thoughts about technology,Java and life</description>
	<lastBuildDate>Tue, 07 Sep 2010 15:26:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
	
<!-- Start Of Script Generated By WP-PostViews Plus -->
<script type='text/javascript' src='http://www.javachen.com/wp-includes/js/jquery/jquery.js?ver=1.4.2'></script>
<script type="text/javascript">
/* <![CDATA[ */
jQuery.ajax({type:'GET',url:'http://www.javachen.com/wp-content/plugins/wp-postviews-plus/postviews_plus.php',data:'todowppvp=add&type=cat&id=113_1',cache:false,dataType:'script'});
/* ]]> */
</script>
<!-- End Of Script Generated By WP-PostViews Plus -->
	<item>
		<title>网络流传的75道逻辑思维题及其解法</title>
		<link>http://www.javachen.com/2010/03/75-puzzles-and-answers-on-the-internet/</link>
		<comments>http://www.javachen.com/2010/03/75-puzzles-and-answers-on-the-internet/#comments</comments>
		<pubDate>Fri, 19 Mar 2010 15:04:59 +0000</pubDate>
		<dc:creator>JavaChen</dc:creator>
				<category><![CDATA[C/Algorithm]]></category>

		<guid isPermaLink="false">http://www.javachen.com/?p=1158</guid>
		<description><![CDATA[【1】 假设有一个池塘，里面有无穷多的水。现有2个空水壶，容积分别为5升和6升。 问题是如何只用这2个水壶从池塘里取得3升的水。 取5升, 倒在6升中; 再取5升, 倒入6升水壶至其满, 5升水壶中剩下4升;将6升水壶倒空, 将5升水壶中4升水倒入6升水壶, 再取5升水, 倒入6升水壶至其满, 5升水壶中剩余3升. 答题完毕. 【2】 周雯的妈妈是豫林水泥厂的化验员。 一天，周雯来到化验室做作业。做完后想出去玩。 &#8220;等等，妈妈还要考你一个题目，&#8221;她接着说，&#8221;你看这6只做化验用的玻璃杯，前面3只盛满了水，后面3只是空的。你 能只移动1只玻璃杯，就便盛满水的杯子和空杯子间隔起来 吗?&#8221; 爱动脑筋的周雯，是学校里有名的&#8221;小机灵&#8221;，她只想了一会儿就做到了。 请你想想看，&#8221;小机灵&#8221;是怎样做的? 将第二只杯子的水倒入第5只杯子. 则为, 满, 空, 满, 空, 满, 空. 答题完毕. 【3】 三个小伙子同时爱上了一 个姑娘，为了决定他们谁能娶这个姑娘，他们决定用手枪进行一次决斗。小李的命中率是30％，小黄比他好些，命中率是50％，最出色的枪手是小林，他从不失 误，命中率是100％。由于这个显而易见的事实，为公平起见，他们决定按这样的顺序：小李先开枪，小黄第二，小林最后。然后这样循环，直到他们只剩下一个 人。那么这三个人中谁活下来的机会最大呢？他们都应该采取什么样的策略？小李存活概率最大. 1. 小李有三个选择, 空枪, 射击小黄, 射击小林. 小李不会选择射击小黄, 因有30% 概率小黄死亡, 小林涉及, 小李必死, 死亡概率 30%; 小李不会选择射击小林, 因有30% 概率小林死亡, 小黄回击, 小李可能死, 死亡概率为 3 0% [...]]]></description>
			<content:encoded><![CDATA[<p>【1】 假设有一个池塘，里面有无穷多的水。现有2个空水壶，容积分别为5升和6升。<br />
问题是如何只用这2个水壶从池塘里取得3升的水。<br />
取5升, 倒在6升中;<br />
再取5升, 倒入6升水壶至其满, 5升水壶中剩下4升;将6升水壶倒空, 将5升水壶中4升水倒入6升水壶, 再取5升水, 倒入6升水壶至其满, 5升水壶中剩余3升.<br />
答题完毕. <span id="more-1158"></span><br />
【2】 周雯的妈妈是豫林水泥厂的化验员。 一天，周雯来到化验室做作业。做完后想出去玩。 &#8220;等等，妈妈还要考你一个题目，&#8221;她接着说，&#8221;你看这6只做化验用的玻璃杯，前面3只盛满了水，后面3只是空的。你 能只移动1只玻璃杯，就便盛满水的杯子和空杯子间隔起来 吗?&#8221; 爱动脑筋的周雯，是学校里有名的&#8221;小机灵&#8221;，她只想了一会儿就做到了。 请你想想看，&#8221;小机灵&#8221;是怎样做的?<br />
将第二只杯子的水倒入第5只杯子. 则为, 满, 空, 满, 空, 满, 空.<br />
答题完毕.<br />
【3】 三个小伙子同时爱上了一 个姑娘，为了决定他们谁能娶这个姑娘，他们决定用手枪进行一次决斗。小李的命中率是30％，小黄比他好些，命中率是50％，最出色的枪手是小林，他从不失 误，命中率是100％。由于这个显而易见的事实，为公平起见，他们决定按这样的顺序：小李先开枪，小黄第二，小林最后。然后这样循环，直到他们只剩下一个 人。那么这三个人中谁活下来的机会最大呢？他们都应该采取什么样的策略？小李存活概率最大.<br />
1. 小李有三个选择, 空枪, 射击小黄, 射击小林.<br />
小李不会选择射击小黄, 因有30% 概率小黄死亡, 小林涉及, 小李必死, 死亡概率 30%;</p>
<p>小李不会选择射击小林, 因有30% 概率小林死亡, 小黄回击, 小李可能死, 死亡概率为 3<br />
0% * 50% = 15%;<br />
小李会选择空枪, 因为小黄必然射击小林, 小林死亡概率 50%;<br />
小林若不死, 必然射击小黄, 小黄死亡概率 50% *100% = 50%;<br />
小李死亡概率为0.<br />
2. 此时,小黄和小林中间必然死亡一人. 小李可能面对小黄, 可能面对 小林.<br />
面对小黄, 生存概率 30% + 70% *50% = 65%<br />
面对小林 生存概率 30% + 70%*100% = 30%<br />
汇总生存概率为:<br />
小李, 65% * 50% + 30%*50% = 47.5 %<br />
小黄 50%* 70%= 35%<br />
小林 50%* 70%= 35%<br />
因此小李生存概率最低. 采取方法如上所述.<br />
答题完毕</p>
<p>【4】一间囚房里关押着两个犯人。每天监狱都会为这间囚房提供一罐汤，让这两个犯人自己来分。起初，这两个 人经常会发生争执，因为他们总是有人认为对方的汤比自己的多。<br />
后来他们找到了一个两全其美的办法：一个人分汤，让另一个人先选。于是争端就这么解决了。可 是，现在这间囚房里又加进来一个新犯人，现在是三个人来分汤。必须寻找一个新的方法来维持他们之间的和平。该怎么办呢？<br />
按：心理问题，不是逻辑问题<br />
让第一个人将汤分成他认为均匀的三份;<br />
让第二个人将其中两份数汤重新分配, 分成他认为均匀的2份;<br />
让第三个人第一个取汤, 第二个人第二个取汤, 第一个人第三个取汤.<br />
答题完毕.<br />
【5】在一张长方形的桌面上放了n个一样大小的圆形硬币。这些硬币中可能有一些不完全在桌面内，也可能有一些彼此重叠；当再多放一个硬币而它的圆心在桌面内时，新放的硬币便必定与原先某些硬币重叠。请证明整个桌面可以用4n个硬币完全覆盖假设硬币半径为1;因为不能放下一个新硬币, 得知桌面任意一点, 到离它最近的硬币的圆心的距离不大于2;</p>
<p>将桌子做田字型分割成四个一样的小长方形, 那么每个小长方形的边长都减半, 因此, 桌面到最近的圆心的距离就小于1. 可以被N个硬币覆盖. 同理大桌子可以被4N个硬币覆盖.</p>
<p>答题完毕.</p>
<p>【6】一个球、一把长度大约是球的直径2/3长度的直尺.你怎样测出球的半径？方法很多，看看谁的比较巧妙灯光下测影子长度, 直尺垂直立于地面, 测量尺子和球各自长度与影子长度,计算比例尺.</p>
<p>答题完毕.<br />
【7】五个大小相同的一元人民币硬币。要求两两相接触，应该怎么摆？<br />
三维坐标系中不能摆放.</p>
<p>任意三硬币构成的平面两两相交, 组成稳定空间A;第四硬币所在平面与该空间相交, 面相交线处于第四硬币平面内, 组成稳定三角形B;第五硬币相交于稳定空间A, 面相交线组成稳定三角形C;已知B, C不在同一平面, 则所在平面平行或相交, 而相交时候, 有且只有一条面相交线;由三角形斜边大于直角边得知, 两平面内硬币映射必然小于实际距离.而硬币不可穿透和延长即实际距离不大于映射;所以不能摆放.<br />
答题完毕.</p>
<p>【8】猜牌问题<br />
S先生、P先生、Q先生他们知道桌子的抽屉里有16张扑克牌：红桃A、Q、4 黑桃J、8、4、2、7、3 草花K、Q、5、4、6 方块A、5。约翰教授从这16张牌中挑出一张牌来，并把这张牌的点数告诉 P先生，把这张牌的花色告诉Q先生。这时，约翰教授问P先生和Q 先生：你们能从已知的点数或花色中推知这张牌是什么牌吗？ 于是，S先生听到如下的对话：P先生：我不知道这张牌。<br />
Q先生：我知道你不知道这张牌。<br />
P先生：现在我知道这张牌了。<br />
Q先生：我也知道了。<br />
听罢以上的对话，S先生想了一想之后，就正确地推出这张牌是什么牌。<br />
请问：这张牌是什么牌？<br />
方片5。<br />
P知道点数，而不知道花色， 不能断定牌， 说明该点数不止一张牌， 得出点数可能为4，<br />
Q, A. 5。<br />
按点数排，<br />
红桃4， 黑桃4， 草花4；<br />
红桃Q， 草花Q；<br />
红桃A， 方块A；<br />
草花5， 方块5。<br />
为便于理解， 按花色排，即<br />
黑桃 4<br />
红桃，4， 红桃Q， 红桃A<br />
草花 4， 草花5， 草花Q<br />
方块 A， 方块 5。<br />
Q知道P 不知道， 说明该花色的牌全部是重复的， 立即得出<br />
方块 A ， 方块 5<br />
红桃A， 红桃 Q ，红桃4<br />
P 说， 我现在知道了。 说明该点数是唯一的，<br />
方块5， 红桃Q ， 红桃4<br />
Q说， 我也知道了。 说明花色是唯一的，<br />
得到 方片5。<br />
答题完毕.<br />
【9】一个教授逻辑学的教授，有三个学生，而且三个学生均非常聪明！一天教授给他们出了一个题，教授在每个人脑门上贴了一张纸条并告诉他们，每个人的纸条上都写了一个正整数，且某两个数的和等于第三个！（每个人可以看见另两个数，但看不见自己的）教授问第一个学生：你能猜出自己的数吗？回答：不能，问第二个，不能，第三个，不能，再问第一个，不能，第二个，不能，第三个：我猜出来了，是144！教授很满意的笑了。<br />
请问您能猜出另外两个人的数吗？<br />
问第１次就知道，三个数是：<br />
（１）２，１，１<br />
问第２次就知道，三个数是：<br />
（１）１，２，１；<br />
（２）２，３，１<br />
问第３次就知道，三个数是：<br />
（１）１，１，２；<br />
（２）１，２，３；<br />
（３）２，１，３；<br />
（４）２，３，５<br />
问第４次就知道，三个数是：<br />
（１）３，２，１；<br />
（２）３，１，２；<br />
（３）４，１，３；<br />
（４）４，３，１；<br />
（５）５，２，３；<br />
（６）８，３，５<br />
问第５次就知道，三个数是；<br />
（１）１，３，２；<br />
（２）１，４，３；<br />
（３）２，５，３；<br />
（４）２，７，５；<br />
（５）３，４，１；<br />
（６）３，５，２；<br />
（７）４，５，１；<br />
（８）４，７，３；<br />
（９）５，８，３；<br />
（１０）８，１３，５<br />
问第６次就知道，三个数是：<br />
（１）１，３，４；<br />
（２）１，４，５；<br />
（３）２，５，７；<br />
（４）２，７，９；<br />
（５）３，１，４；<br />
（６）３，２，５；<br />
（７）３，４，７；<br />
（８）３，５，８；<br />
（９）４，１，５；<br />
（１０）４，３，７；<br />
（１１）４，５，９；<br />
（１２）４，７，１１；<br />
（１３）５，２，７；<br />
（１４）５，８，１３；<br />
（１５）８，３，１１；<br />
（１６）８，１３，２１</p>
<p>题目是问到第６次时知道，代入第３个数144，得到的五组解是：<br />
（１）１，３，４； 1*36=36 3*36=108 4*38=144<br />
（４）２，７，９； 2*16=32 7*16=112 9*16=144<br />
（５）３，１，４； 3*36=108 1*36=36 4*38=144<br />
（８）３，５，８； 3*18=54 5*18=90 8*18=144<br />
（11）４，５，９； 4*16=64 5*16=80 9*16=144<br />
答题完毕</p>
<p>【10】某城市发生了一起汽车撞人逃跑事件<br />
该城市只有两种颜色的车,蓝色15% 绿色85%<br />
事发时有一个人在现场看见了<br />
他指证是蓝车<br />
但是根据专家在现场分析,当时那种条件能看正确的可能性是80%<br />
那么,肇事的车是蓝车的概率到底是多少?<br />
80% + 20%*15%= 83%<br />
答题完毕</p>
<p>【11】有一人有240公斤 水，他想运往干旱地区赚钱。他每次最多携带60公斤，并且每前进一公里须耗水1公斤（均匀耗水）。假设水的价格在出发地为0，以后，与运输路程成正比， （即在10公里处为10元/公斤，在20公里处为20元/公斤&#8230;&#8230;），又假设他必须安全返回，请问，他最多可赚多少钱？<br />
假设各汽车折返点之间距离依次为x,y,z,t各趟汽车x这一段的耗水应由第1辆承担，它相当于把240升水的1部分运到了X处，应有下面推导，其他各辆车推理相同<br />
(240-8x)*x应极大且8x&lt;=60<br />
解得x = 7.5,在X处卖水60-8x=0<br />
(180-6y)*(7.5+y)应极大且6y&lt;=60<br />
解得y = 10 在Y处卖水60-6y=0<br />
(120-4z)*(17.5+z)应极大且4z&lt;=60<br />
解得z=6.25在Z处卖水60-4z=35<br />
(60-2t)*(23.75+t)应极大且2t&lt;=60<br />
解得t=3.125在t处卖水60-2t=53.75<br />
共卖钱53.75*(3.125+6.25+10+7.5)+35*(6.25+10+7.5)=2275.78125<br />
答题完毕</p>
<p>【12】现在共有100匹马跟100块石头，马分3种，大型马；中型马跟小型马。其中一匹大马一次可以驮3块石头，中型马可以驮2块，而小型马2头可以驮一块石头。问需要多少匹大马，中型马跟小型马？（问题的关键是刚好必须是用完100匹马）</p>
<p>设有大马X， 中马 Y， 小马 Z。<br />
3x + 2y+ 0.5 Z =100<br />
X + y + Z =100<br />
得到<br />
5x + 3y =100， 即 3y= 100-5x= 5(20-x)<br />
得到Y 必然是5 的倍数。<br />
Y=5，X=17，Z=100-22=78</p>
<p>Y=10，X=14，Z=100-24=76</p>
<p>Y=15，X=11，Z=100-26=74</p>
<p>Y=20，X=8，Z=100-28=72</p>
<p>Y=25，X=5，Z=100-30=70</p>
<p>Y=30，X=2，Z=100-32=68<br />
答题完毕<br />
【13】1=5 2=15 3=215 4=2145 那么5=?<br />
5=1<br />
答题完毕<br />
【14】有2n个人排队进电影院，票价是50美分。在这2n个人当中，其中n个人只有50美分，另外n个人有1美元（纸票子）。愚蠢的电影院开始卖票时1分钱也没有。<br />
问： 有多少种排队方法 使得 每当一个拥有1美元买票时，电影院都有50美分找钱<br />
注：<br />
1美元=100美分<br />
拥有1美元的人，拥有的是纸币，没法破成2个50美分<br />
(P2n)/ 2<br />
每一种可以找钱的方法， 让50分的人和100分的人颠倒位置， 即不能有足够的找钱。<br />
每一种不可以找钱的方法， 让两种人颠倒位置， 就能够有足够的找钱。<br />
所以对2N取排列组合， 再除以2即可。<br />
答题完毕<br />
【15】一个人花8块钱买了一只鸡，9块钱卖掉了，然后他觉得不划算，花10块钱又买回来了，11块卖给另外一个人。问他赚了多少?<br />
直接盈利，<br />
第一次交易， 9－8 ＝1<br />
第二次交易， 11－10 ＝1<br />
机会成本，<br />
11－8 ＝ 3<br />
所以此人亏损1元。<br />
【16】有一种体育竞赛共含M个项目，有运动员A，B，C参加，在每一项目中，第一,第二,第三名分别的X，Y，Z分，其中X,Y,Z为正整数且X&gt;Y&gt;Z。最后A得22分，B与C均得9分，B在百米赛中取得第一。求M的值，并问在跳高中谁得第二名。<br />
M （X + Y + Z）= 22+ 9 +9= 40<br />
其中，X + Y + Z&gt;=6， M&gt;＝2<br />
存在<br />
M =2, X + Y + Z=20<br />
M =5， X + Y + Z=8<br />
M＝2 时， B 获得第一， 说明第一分数小于9， A不可能获得22。排除<br />
所以M ＝5. 仅仅存在两种分数可能分布。<br />
X＝ 5， Y =2, z =1<br />
X =4, Y =3, Z =1<br />
当第一名获得分数为4时，B 需要在4场比赛中获得5分。即<br />
3T＋U=5.<br />
T + U =4. 无整数解，排除。<br />
所以，M＝5，X＝ 5， Y =2, z =1。<br />
比赛1， 第一名A， 第二名，C， 第三名B<br />
比赛2， 第一名A， 第二名，C， 第三名B<br />
比赛3， 第一名A， 第二名，C， 第三名B<br />
比赛4， 第一名A， 第二名，C， 第三名B<br />
比赛5， 第一名 B， 第二名 A , 第三名 C。 此比赛确定为百米赛跑。<br />
所以跳高第二名为C。<br />
答题完毕<br />
【17】前提：<br />
1 有五栋五种颜色的房子<br />
2 每一位房子的主人国籍都不同<br />
3 这五个人每人只喝一种饮料，只抽一种牌子的香烟，只养一种宠物<br />
4 没有人有相同的宠物，抽相同牌子的香烟，喝相同的饮料<br />
提示：<br />
１　 英国人住在红房子里<br />
２　 瑞典人养了一条狗<br />
３　 丹麦人喝茶<br />
４　 绿房子在白房子左边<br />
５　 绿房子主人喝咖啡<br />
６　 抽ＰＡＬＬ　ＭＡＬＬ烟的人养了一只鸟<br />
７　 黄房子主人抽ＤＵＮＨＩＬＬ烟<br />
８　 住在中间那间房子的人喝牛奶<br />
９　 挪威人住第一间房子<br />
１０　抽混合烟的人住在养猫人的旁边<br />
１１　养马人住在抽ＤＵＮＨＩＬＬ烟的人旁边<br />
１２　抽ＢＬＵＥ　ＭＡＳＴＥＲ烟的人喝啤酒<br />
１３　德国人抽ＰＲＩＮＣＥ烟<br />
１４　挪威人住在蓝房子旁边<br />
１５　抽混合烟的人的邻居喝矿泉水<br />
问题是：谁养鱼？？？<br />
房间1 房间2 房间3 房间4 房间5<br />
国籍 挪威人 丹麦人 英国人 德国人 瑞典人<br />
颜色 黄色 蓝色 红色 绿色 白色<br />
饮料 矿泉水 茶 牛奶 咖啡 啤酒<br />
香烟 Dunhill烟 混合烟 Pall Mall烟 Price烟 blue Master<br />
宠物 猫 马 鸟 鱼 狗<br />
推理过程过于繁琐， 用6 X 6表格法填写，关键在于决定矿泉水的位置。得到结论如上。</p>
<p>所以， 德国人养鱼。<br />
答题完毕。<br />
【18】5个人来自不同地方，住不同房子，养不同动物，吸不同牌子香烟，喝不同饮料，喜<br />
欢不同食物。根据以下线索确定谁是养猫的人。<br />
1． 红房子在蓝房子的右边，白房子的左边（不一定紧邻）<br />
2． 黄房子的主人来自香港，而且他的房子不在最左边。<br />
3． 爱吃比萨的人住在爱喝矿泉水的人的隔壁。<br />
4． 来自北京的人爱喝茅台，住在来自上海的人的隔壁。<br />
5． 吸希尔顿香烟的人住在养马人的右边隔壁。<br />
6． 爱喝啤酒的人也爱吃鸡。<br />
7． 绿房子的人养狗。<br />
8． 爱吃面条的人住在养蛇人的隔壁。<br />
9． 来自天津的人的邻居（紧邻）一个爱吃牛肉，另一个来自成都。<br />
10．养鱼的人住在最右边的房子里。<br />
11．吸万宝路香烟的人住在吸希尔顿香烟的人和吸“555”香烟的人的中间（紧邻）<br />
12．红房子的人爱喝茶。<br />
13．爱喝葡萄酒的人住在爱吃豆腐的人的右边隔壁。<br />
14．吸红塔山香烟的人既不住在吸健牌香烟的人的隔壁，也不与来自上海的人相邻。<br />
15．来自上海的人住在左数第二间房子里。<br />
16．爱喝矿泉水的人住在最中间的房子里。<br />
17．爱吃面条的人也爱喝葡萄酒。<br />
18．吸“555”香烟的人比吸希尔顿香烟的人住的靠右<br />
此题同上题一样用表格法推理6 ×7， 过程略。<br />
表格如下。<br />
房间1 房间2 房间3 房间4 房间5<br />
地方 北京 上海 香港 天津 成都<br />
动物 马 狗 蛇 猫 鱼<br />
香烟 健康牌 希尔顿 万宝路 555 红塔山<br />
饮料 茅台 葡萄酒 矿泉水 茶 啤酒<br />
食物 豆腐 面条 牛肉 比萨 鸡<br />
颜色 蓝色 绿色 黄色 红色 白色<br />
答题完毕。</p>
<p>【19】斗地主附残局<br />
地主手中牌2、K、Q、J、10、9、8、8、6、6、5、5、3、3、3、3、7、7、7、7<br />
长工甲手中牌大王、小王、2、A、K、Q、J、10、Q、J、10、9、8、5、5、4、4<br />
长工乙手中牌2、2、A、A、A、K、K、Q、J、10、9、9、8、6、6、4、4<br />
三家都是明手，互知底牌。要求是：在三家都不打错牌的情况下，地主必须要么输要么赢。<br />
问：哪方会赢？<br />
由于规则不同， 得出结果不同。<br />
暂定规则为： 单张， 双张， 5张（含）以上顺，连续三对以上顺（含），(出顺时候最大顺到A), 三张带一张，三张单出，四张为炸弹， 大小王可分开出， 也可一起出当作最强大的炸弹。地主一方，长工为另一方。地主为先出牌的一方。<br />
地主手上20张， 两长工手上各17张。<br />
根据博弈论决策因素比，获得胜利因素多的一方胜利。<br />
单张，<br />
地主胜利因素，29+22+19+16+13+16+32+12+8 =167<br />
长工胜利因素 20+20+57+76+54+51+48+45+42+24+12+8+16= 473<br />
双张,<br />
地主胜利因素,8+2+3+4= 17<br />
长工胜利因素,4+2+3+7+7+7+7+7+7= 51<br />
5张顺,<br />
地主胜利因素,1<br />
长工胜利因素,1<br />
6张顺,<br />
地主胜利因素,0<br />
长工胜利因素,1<br />
7张顺,<br />
地主胜利因素,0<br />
长工胜利因素,1</p>
<p>对顺,<br />
地主胜利因素,0<br />
长工胜利因素,1<br />
三张带一张,<br />
地主胜利因素,0<br />
长工胜利因素,9<br />
三张单出,<br />
地主胜利因素,0<br />
长工胜利因素,2<br />
炸弹,<br />
地主胜利因素,2<br />
长工胜利因素,1<br />
地主综合胜利因素1, 长工综合胜利因素7.<br />
所以长工赢.</p>
<p>【20】一楼到十楼的每层电梯门口都放着一颗钻石，钻石大小不一。你乘坐电梯从一楼到十楼，每层楼电梯门都会打开一次，只能拿一次钻石，问怎样才能拿到最大的一颗？<br />
前三个比较大小， 对于最大的有一个概念；中间3个作为参考，确认 最大的一批的平均水平；在最后4个中选择一个属于最大一批的， 闭上眼睛不再观察之后的。 这就是最大的一颗。</p>
<p>答题完毕.</p>
<p>【21】U2合唱团在17分钟 内得赶到演唱会场，途中必需跨过一座桥，四个人从桥的同一端出发，你得帮助他们到达另一端，天色很暗，而他们只有一只手电筒。一次同时最多可以有两人一起 过桥，而过桥的时候必须持有手电筒，所以就得有人把手电筒带来带去，来回桥两端。手电筒是不能用丢的方式来传递的。四个人的步行速度各不同，若两人同行则 以较慢者的速度为准。Bono需花1分钟过桥，Edge需花2分钟过桥，Adam需花5分钟过桥，Larry需花10分钟过桥。他们要如何在17分钟内过 桥呢？<br />
2分钟与1分钟同时过去，2分钟独自回来， 耗时4分钟；<br />
5分钟与10分钟同时过去， 1分钟独自回来， 耗时11分钟；<br />
2分钟和1分钟同时过去， 耗时2分钟<br />
共耗时17分钟。<br />
答题完毕。</p>
<p>【22】一个家庭有两个小孩，其中有一个是女孩，问另一个也是女孩的概率（假定生男生女的概率一样）<br />
50％<br />
答题完毕。<br />
【23】为什么下水道的盖子是圆的？<br />
因为同等大小的面积，只有圆形的在移动中不会掉下去。<br />
答题完毕。<br />
【24】有7克、2克砝码各一个，天平一只，如何只用这些物品三次将140克的盐分成50、9<br />
0克各一份？<br />
第一次， 将盐分为两个 70克， 取出其中一份；<br />
第二次， 利用两个砝码称出9克；<br />
第三次， 利用9克盐和2克砝码称出11克；<br />
于是称量出20克， 倒入另一份70克中， 获得50克， 90克。<br />
答题完毕。<br />
【25】芯片测试：有2k块芯片，已知好芯片比坏芯片多．请设计算法从其中找出一片<br />
好芯片，说明你所用的比较次数上限．<br />
其中：好芯片和其它芯片比较时，能正确给出另一块芯片是好还是坏．<br />
坏芯片和其它芯片比较时，会随机的给出好或是坏。<br />
任意拿两片芯片互相测试，则有<br />
1）结果都为真，则说明两片都为真，或者都为假。<br />
2）其他结果，则最少有一为假。</p>
<p>在任意偶数多的芯片里，如果好芯片多于坏芯片，将所有芯片两两分组，根据抽屉原理，则有<br />
1）必有两个好芯片分在一组。<br />
2）同为好芯片的组数一定多于同为坏芯片的组数。</p>
<p>测试流程<br />
1）将芯片两两分组，比如1和2，3和4。。。。2k-1和2k。互相测试，则必有结果同为真的组。<br />
2）保留结果同为真的组，丢弃其他组。必有好芯片组多于坏芯片组。（所以当只有两组或者一组同为真时，则必为真，测试结束）<br />
3）结果同为真的组芯片必定同好或者同坏，所以可以丢弃一半。从所有同真组中任意取出一个丢弃另一个，组成新的测试组，继续两两分组，直到同真组只有2个或者1个测试结束<br />
，坚持到最后的就是好芯片。</p>
<p>说明：同真组可能会变成奇数个，当为奇数组时，任意选一组取其中一个（假设为A），在剩余组中各取一个来测试A，如果测试结果A为好芯片过半或者等于一半，则A为好芯片，测试结束。否则A为坏芯片，判定A为好芯片的必为坏芯片，剔除后剩余部分形成新的测试组，继续两两分组。。。</p>
<p>总的原理和淘金差不多，刚开始好的芯片多，在每次剔除芯片时一定要保证剔除的坏芯片数量一定要多于或者等于好芯片的数量，这样就能保证在剩余的芯片中好的一定多于坏的。当组数为奇数时采用投票制，多于半数的投票有效（等于也有效，因为好的多于坏的，相等则被测试的一定为好的）。</p>
<p>因为每次最少剔除一半的芯片，所以最坏情况出现在每次只能剔除一半芯片的时候，按等比数列递减。当有N个芯片时，测试次数为n+(n/2)+(n/4)&#8230;=2n<br />
答题完毕.</p>
<p>【26】话说有十二个鸡蛋，有一个是坏的（重量与其余鸡蛋不同），现要求用天平称三次，称出哪个鸡蛋是坏的！<br />
12个鸡蛋分成每四个一组，A，B，C。<br />
先把球编号1-12，<br />
第一次，先将1-4号放在左边，5-8号放在右边。<br />
1.如果天平平衡，则坏球在9-12号。<br />
第二次将1-3号放在左边，9-11号放在右边。<br />
1.如果右重则坏球在9-11号且坏球较重。<br />
第三次将9号放在左边，10号放在右边。<br />
1.如果右重则10号是坏球且比标准球重；<br />
2.如果平衡则11号是坏球且比标准球重；<br />
3.如果左重则9号是坏球且比标准球重。<br />
2.如果平衡则坏球为12号。<br />
第三次将1号放在左边，12号放在右边。<br />
1.如果右重则12号是坏球且比标准球重；<br />
2.这次不可能平衡；<br />
3.如果左重则12号是坏球且比标准球轻。<br />
3.如果左重则坏球在9-11号且坏球较轻。<br />
第三次将9号放在左边，10号放在右边。<br />
1.如果右重则9号是坏球且比标准球轻；<br />
2.如果平衡则11号是坏球且比标准球轻；<br />
3.如果左重则10号是坏球且比标准球轻。<br />
2.如果左重则坏球在1-8号。<br />
第二次将2-4号拿掉，将6-8号从右边移到左边，把9-11号放<br />
在右边。就是说，把1,6,7,8放在左边，5,9,10,11放在右边。<br />
1.如果右重则坏球在拿到左边的6-8号，且比标准球轻。<br />
第三次将6号放在左边，7号放在右边。<br />
1.如果右重则6号是坏球且比标准球轻；<br />
2.如果平衡则8号是坏球且比标准球轻；<br />
3.如果左重则7号是坏球且比标准球轻。<br />
2.如果平衡则坏球在被拿掉的2-4号，且比标准球重。<br />
第三次将2号放在左边，3号放在右边。<br />
1.如果右重则3号是坏球且比标准球重；<br />
2.如果平衡则4号是坏球且比标准球重；<br />
3.如果左重则2号是坏球且比标准球重。<br />
3.如果左重则坏球在没有被触动的1,5号。如果是1号，<br />
则它比标准球重；如果是5号，则它比标准球轻。<br />
第三次将1号放在左边，2号放在右边。<br />
1.这次不可能右重。<br />
2.如果平衡则5号是坏球且比标准球轻；<br />
3.如果左重则1号是坏球且比标准球重<br />
3.如果右重，则情况和2相反，同样思路即解<br />
答题完毕。</p>
<p>【27】100个人回答五道试题，有81人答对第一题，91人答对第二题，85人答对第三题，79人答对第四题，74人答对第五题，答对三道题或三道题以上的人算及格， 那么，在这100人中，至少有（ ）人及格。<br />
第一题不及格， 19人；<br />
第二题不及格， 9人；<br />
第三题不及格， 15人；<br />
第四题不及格， 21人；<br />
第五题不及格， 26人。<br />
答错3道或3道以上者最多15人。 所以至少85人及格。<br />
答题完毕。<br />
【28】陈奕迅有首歌叫十年<br />
吕珊有首歌叫3650夜<br />
那现在问,十年可能有多少天?<br />
第1年为润年， 则第5年，第9年为闰年。 共3563天<br />
第2年为闰年， 则第6年，第10年为闰年。 共3563天。<br />
第3年为闰年， 则第7年为闰年， 共3652天。<br />
第4年为闰年， 则第8年为闰年， 共3652天。<br />
所以10年可能3653或者3652天。<br />
答题完毕。<br />
【29】<br />
1<br />
1 1<br />
2 1<br />
1 2 1 1<br />
1 1 1 2 2 1<br />
下一行是什么？<br />
读数：<br />
第一行 1， 取数 1<br />
第二行读上一行 1个1， 取数 11<br />
第三行读上一行 2个1， 取数 21<br />
第四行读上一行 1个2，1个1，取数 1211<br />
第五行读上一行 1个1，1个2， 2个1， 取数 111221<br />
第六行读上一行 3个1，2个2，1个1， 取数 312211<br />
所以为， 312211<br />
答题完毕。</p>
<p>【30】烧一根不均匀的绳要用一个小时，如何用它来判断半个小时？<br />
烧一根不均匀的绳,从头烧到尾总共需要1个小时。现在有若干条材质相同的绳子,问如何用烧绳的方法来计时一个小时十五分钟呢? （微软的笔试题）两头一起烧；<br />
取3根， 第一根点两头，第二根点一头，第一根烧完为半小时，此时将第二根另一头点燃，烧完获得15分钟。<br />
答题完毕。<br />
【31】共有三类药，分别重1g,2g,3g，放到若干个瓶子中，现在能确定每个瓶子中只有其中一种药，且每瓶中的药片足够多，能只称一次就知道各个瓶子中都是盛的哪类药吗？<br />
如果有4类药呢？5类呢？N类呢(N可数)？<br />
如果是共有m个瓶子盛着n类药呢(m，n为正整数，药的质量各不相同但各种药的质量已知)？你能只称一次就知道每瓶的药是什么吗？<br />
注：当然是有代价的，称过的药我们就不用了<br />
取1号瓶子1颗，2号瓶子5颗，3号瓶子10颗。一起称量重量。<br />
1，2，3 总重量为 41<br />
1，3，2 总重量为 36<br />
2，1，3 总重量为 37<br />
2，3，1 总重量为 27<br />
3，2，1 总重量为 23<br />
3，1，2 总重量为28<br />
M类药同样处理，答题完毕。<br />
【32】假设在桌上有三个密封 的盒，一个盒中有2枚银币(1银币=10便士)，一个盒中有2枚镍币(1镍币=5便士)，还有一个盒中有1枚银币和1枚镍币。这些盒子被标上10便士、 15便<br />
士和20便士，但每个标签都是错误的。允许你从一个盒中拿出1枚硬币放在盒前，看到这枚硬币，你能否说出每个盒内装的东西呢？<br />
银币 20分，镍币10分， 混合币 15分。将三个盒子分别编号为1，2，3。<br />
每个标签都错误的方法只有两个，2，3，1 或 3，1，2。<br />
在标签为15分的盒子里面， 取出一个硬币。<br />
如果是银币，则，15分的为银币盒子， 10分的为混合币盒子，15分为镍币。<br />
如果是镍币，则，15分的为镍币盒子， 10分的为银币盒子， 10分的为银币。<br />
答题完毕。<br />
【33】有一个大西瓜,用水果刀平整地切,总共切9刀,最多能切成多少份,最少能切成多少份?<br />
主要是过程，结果并不是最重要的<br />
最少10块。<br />
最多 2^9块，即512块。<br />
答题完毕.<br />
【34】一个巨大的圆形水池，周围布满了老鼠洞。猫追老鼠到水池边，老鼠未来得及进洞就掉入水池里。猫继续沿水池边缘企图捉住老鼠（猫不入水）。已知V猫=4V鼠。问老鼠是否有办法摆脱猫的追逐？<br />
当老鼠在中心时候, 用时间 R/ T, 猫用 πR/ 4T.老鼠不能跑掉.<br />
当老鼠不经过圆心时候, 假设圆心角为ɑ.<br />
用时间1/2(R*Rsinɑ)/ V. 猫用时间 (ɑ/ 360)*2πR/ 4V. 因为ɑ小于180, 所以不能跑<br />
掉.<br />
答题完毕.<br />
【35】有三个桶，两个大的可装8斤的水，一个小的可装3斤的水，现在有16斤水装满了两大桶就是8斤的桶，小桶空着，如何把这16斤水分给4个人，每人4斤。没有其他任何工具，<br />
4人自备容器，分出去的水不可再要回来。<br />
8 8 0<br />
8 5 3<br />
8 5 0 3<br />
8 2 3<br />
8 0 3 3 2<br />
8 3 0<br />
5 3 3<br />
5 6 0<br />
2 6 3<br />
2 8 1<br />
2 8 0 3 2 1<br />
2 5 3<br />
7 0 3<br />
7 3 0<br />
4 3 3<br />
4 6 0<br />
1 6 3<br />
1 8 1<br />
1 8 0 4 2 1<br />
1 5 3<br />
4 5 0<br />
0 2 3 4 2 1 4<br />
0 0 0 4 4 4 4<br />
答题完毕.<br />
【36】从前有一位老钟表匠， 为一个教堂装一只大钟。他年老眼花，把长短针装配错了，短针走的速度反而是长针的12倍。装配的时候是上午6点，他把短针指在“6 ”上，长针指在“12”上。老钟表匠装好就回家去了。人们看这钟一会儿7点，过了不一会儿就8点了，都很奇怪，立刻去找老钟表匠。等老钟表匠赶到，已经是 下午7点多钟。他掏出怀表来一对，钟准确无误，疑心人们有意捉弄他，一生气就回去了。这钟还是8点、9点地跑，人们再去找钟表匠。老钟表匠第二天早晨8点 多赶来用表一对，仍旧准确无误。 请你想一想，<br />
老钟表匠第一次对表的时候是7点几分？第二次对表又是8点几分？<br />
在6点，两针成为一直线，这是老钟表匠装配的时间。从六点开始，每增加1 小时5+5/11分，两针再成为一直线。7点之后，两针成为一直线的时间是7点5+5/11分；8点以后，两针成为一直线的时间是8点10+10/11分。<br />
答题完毕.<br />
【37】今有2匹马、3头牛和4只羊，它们各自的总价都不满10000文钱（古时的货币单位）。如果2匹马加上1头牛，或者3 头牛加上1只羊，或者4只羊加上1匹马，那么它们各自的总价都正好是10000文钱了。问：马、牛、羊的单价各是多少文钱？<br />
设马的单价是x，牛的单价是y，羊的单价是z<br />
2x+y=10000……(1)<br />
3y+z=10000……(2)<br />
4z+x=10000……(3)<br />
(1)*4+(2)*2+(3)*2=&gt;<br />
10(x+y+z)=80000<br />
x+y+z=8000<br />
或解出<br />
x=3600<br />
y=2800<br />
z=1600<br />
答题完毕.<br />
【38】一天，harlan的 店里来了一位顾客，挑了25元的货，顾客拿出100元，harlan没零钱找不开，就到隔壁飞白的店里把这100元换成零钱，回来给顾客找了75元零钱。 过一会，飞白来找harlan，说刚才的是假钱，harlan马上给飞白换了张真钱，问harlan赔了多少钱？<br />
100元.<br />
答题完毕.<br />
【39】猴子爬绳<br />
这道力学怪题乍看非常简单，可是据说它却使刘易斯．卡罗尔感到困惑。至于这道怪题是否由这位因《爱丽丝漫游奇境记》而闻名的牛津大学数学专家提出来的，那就不清楚了。总之，在一个不走运的时刻，他就下述问题征询人们的意见:<br />
一根绳子穿过无摩擦力的滑轮，在其一端悬挂着一只10磅重的砝码，绳子的另一端有只猴子，同砝码正好取得平衡。当猴子开始向上爬时，砝码将如何动作呢?<br />
&#8220;真奇怪，&#8221;卡罗尔写道，&#8221;许多优秀的数学家给出了截然不同的答案。普赖斯认为砝码将向上升，而且速度越来越快。克利夫顿(还有哈考特)则认为，砝码将以与猴子一样的速度向上升起，然而桑普森却说，砝码将会向下降!&#8221;</p>
<p>一位杰出的机械工程师说&#8221;这不会比苍蝇在绳子上爬更起作用&#8221;，而一位科学家却认为&#8221;砝码的上升或下降将取决于猴子 吃苹果速度的倒数&#8221;，然而还得从中求出猴子尾巴的平方根。严肃地说，这道题目非常有趣，值得认真推敲。它很能说明趣题与力学问题之间的紧密联系。<br />
砝码向下降.<br />
无外力作用, 联合体重心不变.<br />
答题完毕.</p>
<p>【40】两个空心球，大小及重量相同，但材料不同。一个是金，一个是铅。空心球表面图有相同颜色的油漆。现在要求在不破坏表面油漆的条件下用简易方法指出哪个是金的，哪个是铅的。<br />
相同得力原地旋转两个球, 两球重心到内壁中心距离不同, 线速度不同.转得快得是金球.</p>
<p>答题完毕.</p>
<p>【41】有23枚硬币在桌上，10枚正面朝上。假设别人蒙住你的眼睛，而你的手又摸不出硬币的反正面。让你用最好的方法把这些硬币分成两堆，每堆正面朝上的硬币个数相同。选13个为一堆, 选10个为一堆.然后将10个硬币全部翻面.<br />
答题完毕.<br />
【42】三个村庄A、B、C和三个城镇A、B、C坐落在如图所示的环形山内。由于历史原因，只有同名的村与镇之间才有来往。为方便交通，他们准备修铁路。问题是：如何在这个环形山内修三条铁路连通A村与A镇，B村与B镇，C村与C镇。而这些铁路相互不能相交。（挖山洞、修立交桥都不算，绝对是平面问题）。想出答案再想想这个题说明什么问题。<br />
●●●●●●●●●Ｃ●●●●●●●●●●<br />
● ●<br />
● ●<br />
● ●<br />
Ａ　　　　　　　　Ｃ　　　　　　　　　Ｂ<br />
● ● ●<br />
● ● ●<br />
● ● ●<br />
● Ｂ ● Ａ ●<br />
● ● ●<br />
●●●●●●●●●●●●●●●●●●●●<br />
作图如下:</p>
<p>答题完毕.</p>
<p>【43】屋里三盏灯,屋外三个开关,一个开关仅控制一盏灯,屋外看不到屋里怎样只进屋一次,就知道哪个开关控制哪盏灯?<br />
四盏呢~<br />
三个灯: 打开两个灯, 过一会关闭一个. 进去看亮着的, 不亮但是发热的,不亮也不发热的.区别出来.<br />
四个灯: 打开两个灯, 过一会关闭一个, 然后打开一个新的灯, 不亮但是发热的, 亮但是不发热的, 亮而且发热的, 不亮也不发热的. 区别出来.<br />
答题完毕.</p>
<p>【44】2+7-2+7全部有火柴根组成，移动其中任何一根，答案要求为30<br />
说明：因为书写问题作如下解释，2是由横折横三根组成，7是由横折两根组成<br />
将最后一个加号变成, 217, 将第一个加号变成247.<br />
答题完毕.<br />
【45】5名海盗抢得了窖藏的100块金子，并打算瓜分这些战利品。这是一些讲民主的海盗（当然是他们自己特有的民主），他们的习惯是按下面的方式进行分配：最厉害的一名海盗提出分配方案，然后所有的海盗（包括提出方案者本人）就此方案进行表决。如果50%或更多的海盗赞同此方案，此方案就获得通过并据此分配战利品。否则提出方案的海盗将被扔到海里，然后下一名最厉害的海盗又重复上述过程。所有的海盗都乐于看到他们的一位同伙被扔进海里，不过，如果让他们选择的话，他们还是宁可得一笔现金。他们当然也不愿意自己被扔到海里。所有的海盗都是有理性的，而且知道其他的海盗也是有理性的。此外，没有两名海盗是同等厉害的——这些海盗按照完全由上到下的等级排好了座次，并且每个人都清楚自己和其他所有人的等级。这些金块不能再分，也不允许几名海盗共有金块，因为任何海盗都不相信他的同伙会遵守关于共享金块的安排。这是一伙每人都只为自己打算的海盗。<br />
最凶的一名海盗应当提出什么样的分配方案才能使他获得最多的金子呢？<br />
首先从5号海盗开始，因为他是最安全的，没有被扔下大海的风险，因此他的策略也最为简单，即最好前面的人全都死光光，那么他就可以独得这100枚金币了。接下来看4号，他的生存机会完全取决于前面还有人存活着，因为如果1号到3号的海盗全都喂了鲨鱼，那么在只剩4号与5号的情况下，不管4号提出怎样的分配方案，5号一定都会投反对票来让4号去喂鲨鱼，以独吞全部的金币。哪怕4号为了保命而讨好5号，提出（0，100）这样的方案让5号独占金币，但是5号还有可能觉得留着4号有危险，而投票反对以让其喂鲨鱼。因此理性的4号是不应该冒这样的风险，把存活的希望寄托在5号的随机选择上的，他惟有支持3号才能绝对保证自身的性命。 再来看3号，他经过上述的逻辑推理之后，就会提出（100，0，0）这样的分配方案，因为他知道4号哪怕一无所获，也还是会无条件的支持他而投赞成票的，那么再加上自己的1票就可以使他稳获这100金币了。 但是，2号也经过推理得知了3号的分配方案，那么他就会提出（98，0，1，1）的方案。因为这个方案相对于3号的分配方案，4号和5号至少可以获得1枚金币，理性的4号和5号自然会觉得此方案对他们来说更有利而支持2号，不希望2号出局而由3号来进行分配。这样，2号就可以屁颠屁颠的拿走98枚金币了。 不幸的是，1号海盗更不是省油的灯，经过一番推理之后也洞悉了2号的分配方案。他将<br />
采取的策略是放弃2号，而给3号1枚金币，同时给4号或5号2枚金币，即提出（97，0，1，2，0）或（97，0，1，0，2）的分配方案。由于1号的分配方案对于3号与4号或5号来说，相比2号的方案可以获得更多的利益，那么他们将会投票支持1号，再加上1号自身的1票，97枚金币就可轻松落入1号的腰包了</p>
<p>答题完毕.</p>
<p>【46】他们中谁的存活机率最大？<br />
5个囚犯，分别按1-5号在装有100颗绿豆的麻袋抓绿豆，规定每人至少抓一颗，而抓得最多和最少的人将被处死，而且，他们之间不能交流，但在抓的时候，可以摸出剩下的豆子数<br />
。问他们中谁的存活几率最大？提示：<br />
1，他们都是很聪明的人<br />
2，他们的原则是先求保命，再去多杀人<br />
3，100颗不必都分完<br />
4，若有重复的情况，则也算最大或最小，一并处死<br />
每个人拿的个数必须大于等于2,否则就是死<br />
所以，1号最多敢拿50-2*4=42颗，但这也是死，因为2号就拿41颗，剩下17颗，1号也是死。</p>
<p>所以1号必须让拿了N颗后，再让2号拿后，还剩很多。那么我们把100颗分为5份。</p>
<p>如果1号拿21颗，2号就拿20颗，剩下59颗，肯定有一个人拿的少于20颗，所以1号拿21颗死定。再看1号拿20颗，2号拿21颗的话，剩下也是59颗，可以是20+20+19，2号死定。<br />
那么，看2号拿20颗，剩下60颗，3号如果拿21颗，剩下39颗，可以是20+19，3号死定。所以，接着看3号拿20颗，剩下40颗，那么，4号怎么拿也是死！而且和5号一起死！要不就全部一起死（都拿20颗）3号当然怕同归于尽啊，因为4号5号心想怎么也是个死，不如弄死全部。所以看3号拿19颗，剩下41颗，可以是20+20，20+19。20+21，不管怎么，3号都死定了。</p>
<p>所以，3号只敢拿20颗。因为可以活不成也弄个全体一起死.<br />
那么，4号也同样怕全部20颗的情况，所以，而21颗不能拿，所以，他拿19颗。剩下61颗，可以是20+20+19，20+20+20，20+20+21，他怎么也是个死！<br />
所以，4号没得选择，只能拿20颗。至少可以弄得个全部拿20颗一起同归于尽.<br />
同理！5号也只能拿20颗！<br />
这样下去，1-5号都拿20颗，同归于尽！<br />
因为:任何一个人，拿21个以上或者19个以下(包括)就是单独死或者只死几个.<br />
答题完毕.<br />
【47】有5只猴子在海边发现 一堆桃子,决定第二天来平分.第二天清晨,第一只猴子最早来到,它左分右分分不开,就朝海里扔了一只,恰好可以分成5份,它拿上自己的一份走了.第 2,3,4,5只猴子也遇到同样的问题,采用了同样的方法,都是扔掉一只后,恰好可以分成5份.问这堆桃子至少有多少只？<br />
5*5*5*5*5+1= 726<br />
答题完毕.</p>
<p>【48】话说某天一艘海盗船被天下砸下来的一头牛给击中了,5个倒霉的家伙只好逃难到一个孤岛,发现岛上孤零零的,幸好有有棵椰子树,还有一只猴子!<br />
大家把椰子全部采摘下来放在一起,但是天已经很晚了,所以就睡觉先.晚上某个家伙悄悄的起床,悄悄的将椰子分成5份,结果发现多一个椰子,顺手就给了幸运的猴子,然后又悄悄的藏了一份,然后把剩下的椰子混在一起放回原处,最后还是悄悄滴回去睡觉了.<br />
过了会儿,另一个家伙也悄悄的起床,悄悄的将剩下的椰子分成5份,结果发现多一个椰子,顺手就又给了幸运的猴子,然后又悄悄滴藏了一份,把剩下的椰子混在一起放回原处,最后还是悄悄滴回去睡觉了.<br />
又过了一会 &#8230;<br />
&#8230;<br />
又过了一会 &#8230;<br />
总之5个家伙都起床过,都做了一样的事情<br />
早上大家都起床,各自心怀鬼胎的分椰子了,这个猴子还真不是一般的幸运,因为这次把椰子<br />
分成5分后居然还是多一个椰子,只好又给它了.<br />
问题来了,这堆椰子最少有多少个?<br />
5*5*5*5*5+1= 726<br />
答题完毕.<br />
【49】小明和小强都是张老师的学生，张老师的生日是M月N日，<br />
2人都知道张老师的生日是下列10组中的一天，<br />
张老师把M值告诉了小明，把N值告诉了小强，<br />
张老师问他们知道他的生日是那一天吗？<br />
3月4日 3月5日 3月8日<br />
6月4日 6月7日<br />
9月1日 9月5日<br />
12月1日 12月2日 12月8日<br />
小明说：如果我不知道的话，小强肯定也不知道<br />
小强说：本来我也不知道，但是现在我知道了<br />
小明说：哦，那我也知道了<br />
请根据以上对话推断出张老师的生日是哪一天<br />
答案应该是9月1日。<br />
1）首先分析这10组日期，经观察不难发现，只有6月7日和12月2日这两组日期的日数是唯一的。由此可知，如果小强得知的N是7或者2，那么他必定知道了老师的生日。<br />
2）再分析“小明说：如果我不知道的话，小强肯定也不知道”，而该10组日期的月数分别为3，6，9，12，而且都相应月的日期都有两组以上，所以小明得知M后是不可能知道老师生日的。<br />
3）进一步分析“小明说：如果我不知道的话，小强肯定也不知道”，结合第2步结论，可知小强得知N后也绝不可能知道。<br />
4）结合第3和第1步，可以推断：所有6月和12月的日期都不是老师的生日，因为如果小明得知的M是6，而若小强的N==7，则小强就知道了老师的生日。（由第1步已经推出），同理，如果小明的M==12，若小强的N==2，则小强同样可以知道老师的生<br />
日。即：M不等于6和9。现在只剩下“3月4日 3月5日 3月8日 9月1日9月5日”五组日期。而小强知道了，所以N不等于5（有3月5日和9月5日），此时，<br />
小强的N∈（1，4，8）注：此时N虽然有三种可能，但对于小强只要知道其中的一种，就得出结论。所以有“小强说：本来我也不知道，但是现在我知道了”，<br />
对于我们则还需要继续推理<br />
至此，剩下的可能是“3月4日 3月8日 9月1日”<br />
5）分析“小明说：哦，那我也知道了”，说明M==9，N==1，（N==5已经被排除，3月份的有两组）<br />
答题完毕.<br />
【50】一逻辑学家误入某部 落，被囚于牢狱，酋长欲意放行，他对逻辑学家说：“今有两门，一为自由，一为死亡，你可任意开启一门。现从两个战士中选择一人负责解答你所提的任何一个问 题（Y/N），其中一个天性诚实，一人说谎成性，今后生死任你选择。”逻辑学家沉思片刻，即向一战士发问，然后开门从容离去。逻辑学家应如何发问？<br />
你来自哪个门? 然后向所指向得门走.<br />
答题完毕.<br />
【51】说从前啊,有一个富 人,他有30个孩子,其中15个是已故的前妻所生,其余15个是继室所生,这后一个妇人很想让她自己所生的最年长的儿子继承财产,于是,有一天,他就向他 说:&#8221;亲爱的丈夫啊,你就要老了,我们应该定下来谁将是你的继承人,让我们把我们的30个孩子排成一个圆圈,从他们中的一个数起,每逢到10就让那个孩子 站出去,直到最后剩下哪个孩子,哪个孩子就继承你的财产吧!&#8221;富人一想,我靠,这个题意相当有内涵了,不错,仿佛很公平,就这么办吧~不过,当剔选过程不 断进行下去的时候,这个富人傻眼了,他发现前14个被剔除的孩子都是前妻生的,而且下一个要被剔除的还是前妻生的,富人马上大手一挥,停,现在从这个孩子 倒回去数, 继室,就是这个歹毒的后妈一想,倒数就倒数,我15个儿子还斗不过你一个啊~她立即同意了富人的动议,你猜,到底谁做了继承人呢~<br />
10+11+12+13+14+15+16+17+18+19+20+21+22+23= 198<br />
198/ 30= 6余18.<br />
小孩子站在18号位置即可.<br />
答题完毕.</p>
<p>【52】“有一牧场，已知养牛27头，6天把草吃尽；养牛23头，9天把草吃尽。如果养牛21头，那么几天能把牧场上的草吃尽呢？并且牧场上的草是不断生长的。”<br />
把一头牛一天所吃的牧草看作1，那么就有：</p>
<p>（1）27头牛6天所吃的牧草为：27×6＝162</p>
<p>（这162包括牧场原有的草和6天新长的草。）</p>
<p>（2）23头牛9天所吃的牧草为：23×9＝207</p>
<p>（这207包括牧场原有的草和9天新长的草。）</p>
<p>（3）1天新长的草为：（207－162）÷（9－6）＝15</p>
<p>（4）牧场上原有的草为：27×6－15×6＝72</p>
<p>（5）每天新长的草足够15头牛吃，21头牛减去15头，剩下6头吃原牧场的草：</p>
<p>72÷（21－15）＝72÷6＝12（天）</p>
<p>答题完毕.<br />
53】一个商人骑一头驴要穿越1000公里长的沙漠，去卖3000根胡萝卜。已知驴一次性可驮1000根胡萝卜，但每走一公里又要吃掉一根胡萝卜。问：商人共可卖出多少胡萝卜？<br />
假设出沙漠时有1000根萝卜，那么在出沙漠之前一定不只1000根，那么至少要驮两次才会出沙漠，那样从出发地到沙漠边缘都会有往返的里程，那所走的路程将大于3000公里，故最后能卖出萝卜的数量一定是小于1000根的。<br />
那么在走到某一个位置的时候萝卜的总数会恰好是1000根。<br />
因为驴每次最多驮1000，那么为了最大的利用驴，第一次卸下的地点应该是使萝卜的数量为2000的地点。<br />
因为一开始有3000萝卜，驴必须要驮三次，设驴走X公里第一次卸下萝卜<br />
则：5X=1000（吃萝卜的数量，也等于所行走的公里数）<br />
X=200，也就是说第一次只走200公里<br />
验算：驴驮1000根走200公里时剩800根，卸下600根，返回出发地<br />
前两次就囤积了1200根，第三次不用返回则剩800根，则总共是2000根萝卜了。<br />
第二次驴只需要驮两次，设驴走Y公里第二次卸下萝卜<br />
则：3Y=1000， Y=333.3<br />
验算：驴驮1000根走333.3公里时剩667根，卸下334根，返回第一次卸萝卜地点<br />
第二次在途中会吃掉334根萝卜，到第二次卸萝卜地点是加上卸下的334根，刚好是1000根<br />
。<br />
而此时总共走了：200+333.3=533.3公里，而剩下的466.7公里只需要吃466根萝卜<br />
所以可以卖萝卜的数量就是1000-466=534.<br />
答题完毕.<br />
【54】10箱黄金，每箱100块，每块一两<br />
有贪官，把某一箱的每块都磨去一钱<br />
请称一次找到不足量的那个箱子<br />
编号为1到100箱, 每箱取跟编号相同数目的黄金, 称量. 少多少钱,就是多少编号的箱子不足.<br />
答题完毕.<br />
【55】你让工人为你工作７天，给工人的回报是一根金条。金条平分成相连的７段，你必须在每天结束时都付费，如果只许你两次把金条弄断，你如何给你的工人付费？<br />
分为, 1,2,4 三段.<br />
第一天, 1个环给工人<br />
第二天, 2个环给工人, 拿回一个环<br />
第三天, 1个环给工人<br />
第四天, 4个环给工人, 拿回1个环,2个环<br />
第五天, 一个环给工人<br />
第六天, 2个环给工人,拿回1个环<br />
第七天, 1个环给工人.<br />
答题完毕.</p>
<p>【56】有十瓶药，每瓶里都装有100片药（仿佛现在装一百片的少了，都是十片二十片的，不管，咱们就这么来了），其中有八瓶里的药每片重10克，另有两瓶里的药每片重9克。用一个蛮精确的小秤，只称一次，如何找出份量较轻的那两个药瓶？<br />
编号1至10, 1号取10片, 2号取20片,以此类推.<br />
称量所有取出药片, 缺少多少, 就是哪两个瓶子分量较轻.<br />
答题完毕.</p>
<p>【57】一个经理有三个女儿， 三个女儿的年龄加起来等于13，三个女儿的年龄乘起来等于经理自己的年龄，有一个下属已知道经理的年龄，但仍不能确定经理三个女儿的年龄，这时经理说只有 一个女儿的头发是黑的，然后这个下属就知道了经理三个女儿的年龄。请问三个女儿的年龄分别是多少？为什么？<br />
显然3个女儿的年龄都不为0，要不爸爸就为0岁了，因此女儿的年龄都大于等于1岁。这样可以得下面的情况：1*1*11=11，1*2**10=20，1*3*9=27，1*4*8=32，1*5*7=35，{1*6*6=<br />
36}，{2*2*9=36}，2*3*8=48，2*4*7=56，2*5*6=60，3*3*7=63，3*4*6=72，3*5*5=75，4*4*5=80因为下属已知道经理的年龄，但仍不能确定经理三个女儿的年龄，说明经理是36岁<br />
（因为{1*6*6=36}，{2*2*9=36}），所以3个女儿的年龄只有2种情况，经理又说只有一个女儿的头发是黑的，说明只有一个女儿是比较大的，其他的都比较小，头发还没有长成黑<br />
色的，所以3个女儿的年龄分别为2，2，9！<br />
答题完毕.<br />
【58】有三个人去住旅馆，住 三间房，每一间房$10元，于是他们一共付给老板$30，第二天，老板觉得三间房只需要$25元就够了于是叫小弟退回$5给三位客人，谁知小弟贪心,只<br />
退 回每人$1，自己偷偷拿了$2，这样一来便等于那三位客人每人各花了九元，于是三个人一共花了$27，再加上小弟独吞了不$2，总共是$29。可是当初他 们三个人一共付出$30那么还有$1呢？<br />
小弟独吞的3元已经计量在28元成本中.退回钱数为3*9=27.<br />
1= 28-27.<br />
答题完毕.<br />
【59】有两位盲人，他们都各自买了两对黑袜和两对白袜，八对袜了的布质、大小完全相同，而每对袜了都有一张商标纸连着。两位盲人不小心将八对袜了混在一起。他们每人怎样才能取回黑袜和白袜各两对呢？<br />
把每双袜子的商标撕开，然后每人拿每双的一只答题完毕.<br />
【60】有一辆火车以每小时 15公里的速度离开洛杉矶直奔纽约，另一辆火车以每小时20公里的速度从纽约开往洛杉矶。如果有一只鸟，以30公里每小时的速度和两辆火车同时启动，从洛 杉矶出发，碰到另一辆车后返回，依次在两辆火车来回飞行，直到两辆火车相遇，请问，这只小鸟飞行了多长距离？<br />
S1= (15+ 20)t<br />
S2= 30t<br />
得到S2= 6/7 S1. 小鸟飞行两地距离的6/7.<br />
答题完毕.</p>
<p>【61】你有两个罐子，50个红色弹球，50个蓝色弹球，随机选出一个罐子，随机选取出一个弹球放入罐子，怎么给红色弹球最大的选中机会？在你的计划中，得到红球的准确几率是多少？<br />
一个罐子放一个红球，另一个罐子放49个红球和50个蓝球，概率接近75%<br />
答题完毕.<br />
【62】你有四个装药丸的罐子，每个药丸都有一定的重量，被污染的药丸是没被污染的重量＋1.只称量一次，如何判断哪个罐子的药被污染了？<br />
1号罐取一个药片, 2号罐取两个药片,3号罐取3个药片, 4号罐取4个药片.<br />
称量总重量, 比正常重量重几, 就是几号罐子被污染了.<br />
答题完毕.<br />
【63】对一批编号为1～100，全部开关朝上(开)的灯进行以下*作：凡是1的倍数反方向拨一次开关；2的倍数反方向又拨一次开关；3的倍数反方向又拨一次开关……问：最后为关熄状态的灯的编号。<br />
【64】想象你在镜子前，请问，为什么镜子中的影像可以颠倒左右，却不能颠倒上下？</p>
<p>因为镜子和你平行.<br />
如果镜子与人不平行, 就可以颠倒上下.<br />
答题完毕.<br />
【65】一群人开舞会，每人头 上都戴着一顶帽子。帽子只有黑白两种，黑的至少有一顶。每个人都能看到其它人帽子的颜色，却看不到自己的。主持人先让大家看看别人头上戴的是什幺帽子，然 后关灯，如果有人认为自己戴的是黑帽子，就打自己一个耳光。第一次关灯，没有声音。于是再开灯，大家再看一遍，关灯时仍然鸦雀无声。一直到第三次关灯，才 有劈劈啪啪打耳光的声音响起。问有多少人戴着黑帽子？<br />
应该是三个人：<br />
1，若是两个人，设A、B是黑帽子,第二次关灯就会有人打耳光。原因是A看到B第一次没打耳光，就知道B也一定看到了有带黑帽子的人，可A除了知道B带黑帽子外，其他人都是白帽子，就可推出他自己是带黑帽子的人！同理B也是这么想的，这样第二次熄灯会有两个耳光的声音。<br />
2，如果是三个人，A,B,C. A第一次没打耳光，因为他看到B,C都是带黑帽子的；而且假设自己带的是白帽子，这样只有BC戴的是黑帽子；按照只有两个人带黑帽子的推论，第二次应该有人打耳光；可第二次却没有。。。于是他知道B和C一定看到了除BC之外的其他人带了黑帽子，于是他知道BC看到的那个人一定是他，所以第三次有三个人打了自己一个耳光！<br />
答题完毕.<br />
【66】两个圆环，半径分别是1和2，小圆在大圆内部绕大圆圆周一周，问小圆自身转了几周？如果在大圆的外部，小圆自身转几周呢？<br />
小圆周长2π, 大圆周长4π.<br />
小圆饶大圆内部一周, 小圆转2圈.<br />
在大圆外部, 小圆转2圈.<br />
答题完毕.<br />
【67】 1元钱一瓶汽水，喝完后两个空瓶换一瓶汽水，问：你有20元钱，最多可以喝到几瓶汽水？</p>
<p>找人借一个瓶子.20元买汽水, 20个瓶子换10汽水, 10空瓶换5汽水,5空瓶加上借来的空瓶换三汽水, 三瓶子换1汽水,剩余1瓶子, 1空瓶加上剩余空瓶换1汽水, 剩余1空瓶.还给别人20+ 10+5+3+1+1 = 40瓶.<br />
或, 两个空瓶换一瓶汽水.得出汽水(不含瓶)成本等于空瓶成本, 为5毛. 20块等于40个5毛.所以40瓶.<br />
答题完毕.<br />
【68】有3顶红帽子，4顶黑 帽子，5顶白帽子。让10个人从矮到高站成一队，给他们每个人头上戴一顶帽子。每个人都看不见自己戴的帽子的颜色，却只能看见站在前面那些人的帽子颜色。 （所以最后一个人可以看见前面9个人头上帽子的颜色，而最前面那个人谁的帽子都看不见。现在从最后那个人开始，问他是不是知道自己戴的帽子颜色，如果他回 答说不知道，就继续问他前面那个人。假设最前面那个人一定会知道自己戴的是黑帽子。为什么？<br />
一共3红4黑5白,第十个人不知道的话,可推出前9个人的所有可能情况:<br />
红 黑 白<br />
3 3 3<br />
3 2 4<br />
3 1 5<br />
2 3 4<br />
2 2 5<br />
1 3 5<br />
如果第九个人不知道的话，可推出前8个人的所有可能情况：<br />
红 黑 白<br />
1 2 5<br />
1 3 4<br />
2 1 5<br />
2 2 4<br />
2 3 3<br />
3 1 4<br />
3 2 3<br />
由此类推可知，当推倒第六个人时，会发现他已经肯定知道他自己戴的是什么颜色的帽子了．<br />
答题完毕.<br />
【69】假设排列着100个乒乓球，由两个人轮流拿球装入口袋，能拿到第100个乒乓球的人为胜利者。条件是：每次拿球者至少要拿1个，但最多不能超过5个，问：如果你是最先拿球的人，你该拿几个？以后怎么拿就能保证你能得到第100个乒乓球？<br />
拿出4个, 然后按照6的倍数和另外一人分别拿球. 即<br />
另外一人拿1个, 我拿5个<br />
另外一人拿2个, 我拿4个<br />
另外一人拿3个, 我拿3个<br />
另外一人拿4个, 我拿2个<br />
另外一人拿5个, 我拿1个.<br />
最终100个在我手上.<br />
答题完毕.<br />
【70】卢姆教授说：“有一次 我目击了两只山羊的一场殊死决斗，结果引出了一个有趣的数学问题。我的一位邻居有一只山羊，重54磅，它已有好几个季度在附近山区称王称霸。<br />
后来某个好事 之徒引进了一只新的山羊，比它还要重出3磅。开始时，它们相安无事，彼此和谐相处。可是有一天，较轻的那只山羊站在陡峭的山路顶上，向它的竞争对手猛扑过去，那对手站在土丘上迎接挑战，而挑战者显然拥有居高临下的优势。不幸的是，由于猛烈碰撞，两只山羊都一命呜呼了。<br />
现在要讲一讲本题的奇妙之处。对饲养山羊颇有研究，还写过书的乔治．阿伯克龙比说道：“通过反复实验，我发现，动量相当于一个自20英尺高处坠落下来 的30磅重物的一次撞击，正好可以打碎山羊的脑壳，致它死命。”如果他说得不错，那么这两只山羊至少要有多大的逼近速度，才能相互撞破脑壳？你能算出来吗？<br />
自由落体20英尺,速度为20英尺/ 秒<br />
20*30= (54+57)*V<br />
V=50/111 英尺/秒<br />
解答完毕.<br />
【71】据说有人给酒肆的老板娘出了一个难题：此人明明知道店里只有两个舀酒的勺子，分别能舀7两和11两酒，却硬要老板娘卖给他2两酒。聪明的老板娘毫不含糊，用这两个勺子在酒缸里舀酒，并倒来倒去，居然量出了2两酒，聪明的你能做到吗？<br />
7两倒入11两, 再用7两倒入11两装满, 7两中剩余3两, 倒出11两, 将3两倒入11两, 用7两两次倒入11两装满, 7两中剩余6两, 将11两倒出, 将6两倒入, 然后用7两倒入11两, 剩余2两. 于是得到.<br />
答题完毕.<br />
【72】已知： 每个飞机只有一个油箱， 飞机之间可以相互加油（注意是相互，没有加油机） 一箱油可供一架飞机绕地球飞半圈，问题：为使至少一架飞机绕地球一圈回到起飞时的飞机场，至少需要出动几架飞机？（所有飞机从同一机场起飞，而且必须安全 返回机场，不允许中途降落，中间没有飞机场）需要4飞机.<br />
假设需要三架飞机,编号为1,2,3.<br />
三架同时起飞, 飞到1/8 圈处, 1号飞机,给2号,3号,飞机各加上1/8 圈的油, 刚好飞回基地,此时1号,2号满油,继续前飞;飞到2/8 圈时候,2号飞机给1号飞机加油1/8圈油量,刚好飞回基地, 3号飞机满油,继续向前飞行, 到达6/8处无油;<br />
此时重复2号和三号飞机的送油.3号飞机反方向飞行到1/6圈时, 加油1/6圈给给2号飞机,2号飞机向前飞行X圈, 则3号飞机可向前继续送油, 1/6 –2X 圈. 此时3号刚好飞回, 2号满油.当X= 1/6-2X时候获得最大. X =1/18.<br />
1/6 + 1/18= 2/ 9. 少于1/4. 所以不能完成.<br />
类比推,当为4架时, 恰好满足条件.<br />
答题完毕.<br />
【73】在9个点上画10条直线，要求每条直线上至少有三个点？<br />
排列如下所示.X代表点, O代表空格.<br />
X O X<br />
O X O<br />
X X X<br />
O X O<br />
X O X<br />
得到10条.<br />
答题完毕.</p>
<p>【74】一个岔路口分别通向诚实国和说谎国。来了两个人，已知一个是诚实国的，另一个是说谎国的。诚实国永远说实话，说谎国永远说谎话。现在你要去说谎国，但不知道应该走哪条路，需要问这两个人。请问应该怎么问？<br />
我要到你的国家去,请问怎么走?然后走向路人所指方向的相反方向.<br />
答题完毕.<br />
【75】在一天的24小时之中，时钟的时针、分针和秒针完全重合在一起的时候有几次？都分别是什么时间？你怎样算出来的？<br />
两次, 24点和12点.<br />
使用角速度, 讨论分针重合时针时候, 秒针位置.<br />
答题完毕.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javachen.com/2010/03/75-puzzles-and-answers-on-the-internet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>分治法</title>
		<link>http://www.javachen.com/2010/02/algorithm-fenzifa/</link>
		<comments>http://www.javachen.com/2010/02/algorithm-fenzifa/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 13:01:27 +0000</pubDate>
		<dc:creator>JavaChen</dc:creator>
				<category><![CDATA[C/Algorithm]]></category>

		<guid isPermaLink="false">http://www.javachen.com/?p=1013</guid>
		<description><![CDATA[在计算机科学中，分治法是一种很重要的算法。字面上的解释是“分而治之”，就是把一个复杂的问题分成两个或更多的相同或相似的子问题，再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解，原问题的解即子问题的解的合并。 分治法的设计思想是，将一个难以直接解决的大问题，分割成一些规模较小的相同问题，以便各个击破，分而治之。 分治策略是：对于一个规模为n的问题，若该问题可以容易地解决（比如说规模n较小）则直接解决，否则将其分解为k个规模较小的子问题，这些子问题互相独立且与原问题形式相同，递归地解这些子问题，然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。 如果原问题可分割成k个子问题，1&#60;k≤n ，且这些子问题都可解并可利用这些子问题的解求出原问题的解，那么这种分治法就是可行的。由分治法产生的子问题往往是原问题的较小模式，这就为使用递归技 术提供了方便。在这种情况下，反复应用分治手段，可以使子问题与原问题类型一致而其规模却不断缩小，最终使子问题缩小到很容易直接求出其解。这自然导致递 归过程的产生。分治与递归像一对孪生兄弟，经常同时应用在算法设计之中，并由此产生许多高效算法。 分治法所能解决的问题一般具有以下几个特征： 1) 该问题的规模缩小到一定的程度就可以容易地解决 2) 该问题可以分解为若干个规模较小的相同问题，即该问题具有最优子结构性质。 3) 利用该问题分解出的子问题的解可以合并为该问题的解； 4) 该问题所分解出的各个子问题是相互独立的，即子问题之间不包含公共的子子问题。 上述的第一条特征是绝大多数问题都可以满足的，因为问题的计算复杂性一般是随着问题规模的增加 而增加；第二条特征是应用分治法的前提它也是大多数问题可以满足的，此特征反映了递归思想的应用；第三条特征是关键，能否利用分治法完全取决于问题是否具 有第三条特征，如果具备了第一条和第二条特征，而不具备第三条特征，则可以考虑用贪心法或动态规划法。第四条特征涉及到分治法的效率，如果各子问题是不独立的则分治法要做许多不必要的工作，重复地解公共的子问题，此时虽然可用分治法，但一般用动态规划法较好。 人们从大量实践中发现，在用分治法设计算法时，最好使子问题的规模大致相同。换句话说，将一个问题分成大小相等的k个子问题的处理方法是行之有效的。许多 问题可以取 k = 2。这种使子问题规模大致相等的做法是出自一种平衡(balancing)子问题的思想，它几乎总是比子问题规模不等的做法要好。 二分法查找是典型的分治法的例子，下例是java中的二分查找法代码： 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public [...]]]></description>
			<content:encoded><![CDATA[<p>在计算机科学中，分治法是一种很重要的算法。字面上的解释是“分而治之”，就是把一个复杂的问题分成两个或更多的相同或相似的子问题，再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解，原问题的解即子问题的解的合并。<br />
分治法的设计思想是，将一个难以直接解决的大问题，分割成一些规模较小的相同问题，以便各个击破，分而治之。<br />
<span id="more-1013"></span><br />
分治策略是：对于一个规模为n的问题，若该问题可以容易地解决（比如说规模n较小）则直接解决，否则将其分解为k个规模较小的子问题，这些子问题互相独立且与原问题形式相同，递归地解这些子问题，然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。<br />
如果原问题可分割成k个子问题，1&lt;k≤n ，且这些子问题都可解并可利用这些子问题的解求出原问题的解，那么这种分治法就是可行的。由分治法产生的子问题往往是原问题的较小模式，这就为使用递归技 术提供了方便。在这种情况下，反复应用分治手段，可以使子问题与原问题类型一致而其规模却不断缩小，最终使子问题缩小到很容易直接求出其解。这自然导致递 归过程的产生。分治与递归像一对孪生兄弟，经常同时应用在算法设计之中，并由此产生许多高效算法。<br />
分治法所能解决的问题一般具有以下几个特征：<br />
1) 该问题的规模缩小到一定的程度就可以容易地解决<br />
2) 该问题可以分解为若干个规模较小的相同问题，即该问题具有最优子结构性质。<br />
3) 利用该问题分解出的子问题的解可以合并为该问题的解；<br />
4) 该问题所分解出的各个子问题是相互独立的，即子问题之间不包含公共的子子问题。<br />
上述的第一条特征是绝大多数问题都可以满足的，因为问题的计算复杂性一般是随着问题规模的增加 而增加；第二条特征是应用分治法的前提它也是大多数问题可以满足的，此特征反映了递归思想的应用；第三条特征是关键，能否利用分治法完全取决于问题是否具 有第三条特征，如果具备了第一条和第二条特征，而不具备第三条特征，则可以考虑用贪心法或<a href="http://baike.baidu.com/view/1189652.htm" target="_blank">动态规划法</a>。第四条特征涉及到分治法的效率，如果各子问题是不独立的则分治法要做许多不必要的工作，重复地解公共的子问题，此时虽然可用分治法，但一般用动态规划法较好。</p>
<p>人们从大量实践中发现，在用分治法设计算法时，最好使子问题的规模大致相同。换句话说，将一个问题分成大小相等的k个子问题的处理方法是行之有效的。许多 问题可以取 k = 2。这种使子问题规模大致相等的做法是出自一种平衡(balancing)子问题的思想，它几乎总是比子问题规模不等的做法要好。</p>
<p><strong>二分法查找是典型的分治法的例子</strong>，下例是java中的二分查找法代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> BinarySearch <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> BinarySearch<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">int</span> binarySearch<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> datas, <span style="color: #000066; font-weight: bold;">int</span> key<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">int</span> index <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">int</span> low <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">int</span> high <span style="color: #339933;">=</span> datas.<span style="color: #006633;">length</span> <span style="color: #339933;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span>low <span style="color: #339933;">&lt;</span> <span style="color: #339933;">=</span> high<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">int</span> middle <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>low <span style="color: #339933;">+</span> high<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
			<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>key <span style="color: #339933;">==</span> datas<span style="color: #009900;">&#91;</span>middle<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				index <span style="color: #339933;">=</span> middle<span style="color: #339933;">;</span>
				<span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>key <span style="color: #339933;">&gt;</span> datas<span style="color: #009900;">&#91;</span>middle<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				low <span style="color: #339933;">=</span> middle <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>key <span style="color: #339933;">&lt;</span> datas<span style="color: #009900;">&#91;</span>middle<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				high <span style="color: #339933;">=</span> middle <span style="color: #339933;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #000000; font-weight: bold;">return</span> index<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> datas <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #cc66cc;">5</span>, <span style="color: #cc66cc;">6</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">int</span> index <span style="color: #339933;">=</span> BinarySearch.<span style="color: #006633;">binarySearch</span><span style="color: #009900;">&#40;</span>datas, <span style="color: #cc66cc;">6</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>index<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>容易看出，每执行一次算法的while循环，待搜索数组的大小就减小一半。因此，最坏情况下，while循环被执行了O（log n）次。循环体内，运算需要O（1）时间，因此整个算法在最坏情况下的计算时间复杂性为O（log n）。</pre>
<p><strong>利用分治法的思想还可以解决大整数乘法的问题</strong></p>
<p>     通常，在分析一个算法的计算复杂性时，都将加法和乘法运算当作是基本运算来处理，即将执行一次加法或乘法运算所需的计算时间当作一个仅取决于计算机硬件处理速度的常数。<br />
   这个假定仅在计算机硬件能对参加运算的整数直接表示和处理时才是合理的。然而，在某些情况下，我们要处理很大的整数，它无法在计算机硬件能直接表示的范围内进行处理。若用浮点数来表示它，则只能近似地表示它的大小，计算结果中的有效数字也受到限制。若要精确地表示大整数并在计算结果中要求精确地得到所有位数上的数字，就必须用软件的方法来实现大整数的算术运算。<br />
设计如下：<br />
设X和Y都是n位的二进制整数，现在要计算它们的乘积X*Y。<br />
将n位的二进制整数X和Y各分为2段，每段的长为n/2位(为简单起见，假设n是2的幂)。显然问题的答案并不是 A*C*K1+C*D*K2（K1、K2与A、B、C、D无关），也就是说，这样做并没有将问题分解成两个独立的子问题。按照乘法分配律，分解后的计算过程如下：<br />
记：X=A*2n/2+B ，Y=C*2n/2+D。这样，X和Y的乘积为：<br />
X*Y=(A*2n/2+B)(C*2n/2+D)=A*C*2n+(AD+CB)*2n/2+B*D    (1)<br />
模型分析：<br />
如果按式(1)计算X*Y，则我们必须进行4次n/2位整数的乘法(AC，AD，BC和BD)，以及3次不超过n位的整数加法，此外还要做2次移位 (分别对应于式(1)中乘2n和乘2n/2)。所有这些加法和移位共用O(n)步运算。设T(n)是2个n位整数相乘所需的运算总数，则由式(1)，我们有以下(2)式：<br />
T（1）=1<br />
      T（n）=4T(n/2)+O(n)              （2）<br />
由此递归式迭代过程如下：<br />
T(n)=4T(n/2)+cn =4(4T(n/4)+cn/2)+cn<br />
    =16(T(n/8)+ cn/4)+3cn/2+cn =……<br />
    = +4k-1 *2c+4k-2 *4c+……+4c2k-1+c2k<br />
         =O（4k）= O(nlog4)<br />
    =O（n2）<br />
所以可得算法的时间复杂度为T(n)=O(n2)。<br />
模型改进：<br />
可以把X*Y写成另一种形式：<br />
X*Y=A*C*2^n+[(A-B)(D-C)+AC+BD]*2^(n/2)+B*D           (3)<br />
式(3)看起来比式(1)复杂，但它仅需做3次n/2位整数的乘法：AC，BD和(A-B)(D-C)，6次加、减法和2次移位。由此可得:<br />
用解递归方程的迭代公式法，不妨设n=2^k：<br />
     T(n)=3T(n/2)+cn<br />
         =3(3T(n/4)+cn/2)+cn<br />
         =9(T(n/8)+ cn/4)+3cn/2+cn<br />
         =……<br />
         =3^k  +3^(k-1) *2c+3^(k-2) *4c+……+3c2^(k-1)+c2^k<br />
         = O(n^log3)<br />
则得到T(n)=O(n^log3)=O(n^1.59)。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javachen.com/2010/02/algorithm-fenzifa/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>汉诺塔问题</title>
		<link>http://www.javachen.com/2010/02/hanoi/</link>
		<comments>http://www.javachen.com/2010/02/hanoi/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 12:27:14 +0000</pubDate>
		<dc:creator>JavaChen</dc:creator>
				<category><![CDATA[C/Algorithm]]></category>

		<guid isPermaLink="false">http://www.javachen.com/?p=1008</guid>
		<description><![CDATA[【例1】汉诺塔问题描述： 古代有一个梵塔，塔内有3个基座A、B、C，开始时A基座上有64个盘子，盘子大小不等，大的在下，小的在上。有一个老和尚想把这64个盘子从A座移到B座，但每次只允许移动一个盘子，且在移动过程中在3个基座上的盘子都始终保持大盘在下，小盘在上。在移动过程中可以利用C基座做辅助。请编程打印出移动过程 。 算法设计： 用归纳法解此题，约定盘子自上而下的编号为1，2，3，……，n。 首先看一下2阶汉诺塔问题的解，不难理解以下移动过程： 初始状态为 A（1,2） B（）    C（） 第一步后   A（2）   B（）    C（1） 第二步后   A（）    B（2）   C（1） 第三步后   A（）    B（1,2） C（） 如何找出大规模问题与小规模问题的关系，从而实现递归呢？ 把n个盘子抽象地看作“两个盘子”，上面“一个”由1——n-1号组成，下面“一个”就是n号盘子。移动过程如下： 第一步：先把上面“一个”盘子以a基座为起点借助b基座移到c基座。 第二步：把下面“一个”盘子从a基座移到b基座。 第三步：再把c基座上的n-1盘子借助a基座移到b基座。 把n阶的汉诺塔问题的模块记作hanoi(n,a,b,c) a代表每一次移动的起始基座， b代表每一次移动的终点基座， c代表每一次移动的辅助基座 则汉诺塔问题hanoi(n,a,b,c)等价于以下三步： 第一步，hanoi(n-1,a,c,b)； 第二步，把下面“一个”盘子从a基座移到b基座； 第三步， hanoi(n-1,c,b,a)。 算法如下： hanoi (int n,char a,char b,char c) 1) if(n&#62;0)          /*0阶的汉诺塔问题当作停止条件*/ 2) hanoi(n-1,a,c,b); 3) 输出 “ Move dise” ,n.”from pile”,a,” [...]]]></description>
			<content:encoded><![CDATA[<p>【例1】汉诺塔问题描述：<br />
古代有一个梵塔，塔内有3个基座A、B、C，开始时A基座上有64个盘子，盘子大小不等，大的在下，小的在上。有一个老和尚想把这64个盘子从A座移到B座，但每次只允许移动一个盘子，且在移动过程中在3个基座上的盘子都始终保持大盘在下，小盘在上。在移动过程中可以利用C基座做辅助。请编程打印出移动过程 。<br />
<span id="more-1008"></span><br />
算法设计：<br />
用归纳法解此题，约定盘子自上而下的编号为1，2，3，……，n。<br />
首先看一下2阶汉诺塔问题的解，不难理解以下移动过程：<br />
初始状态为 A（1,2） B（）    C（）<br />
第一步后   A（2）   B（）    C（1）<br />
第二步后   A（）    B（2）   C（1）<br />
第三步后   A（）    B（1,2） C（）</p>
<p>如何找出大规模问题与小规模问题的关系，从而实现递归呢？</p>
<p>把n个盘子抽象地看作“两个盘子”，上面“一个”由1——n-1号组成，下面“一个”就是n号盘子。移动过程如下：<br />
第一步：先把上面“一个”盘子以a基座为起点借助b基座移到c基座。<br />
第二步：把下面“一个”盘子从a基座移到b基座。<br />
第三步：再把c基座上的n-1盘子借助a基座移到b基座。</p>
<p>把n阶的汉诺塔问题的模块记作hanoi(n,a,b,c)<br />
a代表每一次移动的起始基座，<br />
b代表每一次移动的终点基座，<br />
c代表每一次移动的辅助基座<br />
则汉诺塔问题hanoi(n,a,b,c)等价于以下三步：<br />
第一步，hanoi(n-1,a,c,b)；<br />
第二步，把下面“一个”盘子从a基座移到b基座；<br />
第三步， hanoi(n-1,c,b,a)。</p>
<p>算法如下：</p>
<p>hanoi (int n,char a,char b,char c)<br />
1) if(n&gt;0)          /*0阶的汉诺塔问题当作停止条件*/<br />
2) hanoi(n-1,a,c,b);<br />
3) 输出 “ Move dise” ,n.”from pile”,a,” to”b);<br />
4) haboi(n-1,c,b,a);<br />
5) endif<br />
}</p>
<p>总结：</p>
<p>通上面的例子可以看出，递归的思路就是将一个负责的数学模型化为较小的数学模型，找出大规模问题与小规模问题的关系，这样通过递归使问题的规模逐渐变小。，然后找出停止条件，即算法可解的最小规模问题。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javachen.com/2010/02/hanoi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>循环与递归</title>
		<link>http://www.javachen.com/2010/02/circle-and-recurrence/</link>
		<comments>http://www.javachen.com/2010/02/circle-and-recurrence/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 12:02:52 +0000</pubDate>
		<dc:creator>JavaChen</dc:creator>
				<category><![CDATA[C/Algorithm]]></category>

		<guid isPermaLink="false">http://www.javachen.com/?p=1004</guid>
		<description><![CDATA[循环体的特点是：“以不变应万变”。 所谓“不变”是指循环体内运算的表现形式是不变的，而每次具体的执行内容却是不尽相同的。在循环体内用不变的运算表现形式去描述各种相似的重复运算。 在使用循环时候，要注意一下几点： 1．设计中要注意算法的效率 2．“自顶向下”的设计方法 3．由具体到抽象设计循环结构 “自顶向下”的设计方法 自顶向下的方法是从全局走向局部、从概略走向详尽的设计方法。自上而下是系统分解和细化的过程。 【例】编算法找出1000以内所有完数 例如，28的因子为1、2、4、7，14，而28=1+2+4+7+14。因此28是“完数”。编算法找出1000之内的所有完数，并按下面格式输出其因子：28  it’s  factors are  1，2，4，7，14。 算法如下： main( ) {int  i,k,j,s,a[20]; for(i=1;i&#60;=1000;i++) {s=1;                        /*两个赋初值语句s=1,k=0 k=0;                         一定要位于外部循环的内部*/ for(j=2;j&#60;i;j++) if (i  mod  j)==0) {s=s+j;  a[k]=j;  k++;} if(i==s) {print(s, “it’s  factors are :”,1); for(j=0;i&#60;k;j++) print(“,”,a[k]); } } } 由具体到抽象设计循环结构 对于不太熟悉的问题，其数学模型或“机械化操作步骤”的不易抽象，下面看一个由具体到抽象设计循环细节的例题。 【例】编写算法：打印具有下面规律的图形。 1 5  2 8  6  3 10  9  7  [...]]]></description>
			<content:encoded><![CDATA[<p>循环体的特点是：“以不变应万变”。<br />
所谓“不变”是指循环体内运算的表现形式是不变的，而每次具体的执行内容却是不尽相同的。在循环体内用不变的运算表现形式去描述各种相似的重复运算。</p>
<p>在使用循环时候，要注意一下几点：<br />
1．设计中要注意算法的效率<br />
2．“自顶向下”的设计方法<br />
3．由具体到抽象设计循环结构<span id="more-1004"></span></p>
<p><strong>“自顶向下”的设计方法</strong><br />
自顶向下的方法是从全局走向局部、从概略走向详尽的设计方法。自上而下是系统分解和细化的过程。<br />
【例】编算法找出1000以内所有完数<br />
例如，28的因子为1、2、4、7，14，而28=1+2+4+7+14。因此28是“完数”。编算法找出1000之内的所有完数，并按下面格式输出其因子：28  it’s  factors are  1，2，4，7，14。<br />
算法如下：<br />
main( )<br />
{int  i,k,j,s,a[20];<br />
for(i=1;i&lt;=1000;i++)<br />
{s=1;                        /*两个赋初值语句s=1,k=0<br />
k=0;                         一定要位于外部循环的内部*/<br />
for(j=2;j&lt;i;j++)<br />
if (i  mod  j)==0)<br />
{s=s+j;  a[k]=j;  k++;}<br />
if(i==s)<br />
{print(s, “it’s  factors are :”,1);<br />
for(j=0;i&lt;k;j++)<br />
print(“,”,a[k]);<br />
}<br />
}<br />
}</p>
<p><strong>由具体到抽象设计循环结构</strong><br />
对于不太熟悉的问题，其数学模型或“机械化操作步骤”的不易抽象，下面看一个由具体到抽象设计循环细节的例题。<br />
【例】编写算法：打印具有下面规律的图形。<br />
1<br />
5  2<br />
8  6  3<br />
10  9  7  4</p>
<p>算法设计：容易发现图形中自然数在矩阵中排列的规律，题目中1，2，3，4所在位置我们称为第1层（主对角线），例图中5，6，7所在位置我们称为第二层，……。一般地，第一层有n个元素，第二层有n-1个元素……<br />
基于以上数据变化规律，以层号作为外层循环，循环变量为i（范围为1——n）；以层内元素从左上到右下的序号作为内循环，循环变量为j（范围为1—— n+1-i）。这样循环的执行过程正好与“摆放”自然数的顺序相同。用一个变量k模拟要“摆放”的数据，下面的问题就是怎么样将数据存储到对应的数组元素。</p>
<p>数组元素的存取，只能是按行、列号操作的。所以下面用由具体到抽象设计循环的“归纳法”，找出数组元素的行号、列号与层号i及层内序号j的关系：</p>
<p>1.每层内元素的列号都与其所在层内的序号j是相同的。因为每层的序号是从第一列开始向右下进行。<br />
2.元素的行与其所在的层号及在层内的序号均有关系,具体地：<br />
第一层行号1——n，行号与j同；<br />
第二层行号2——n，行号比j大1；<br />
第三层行号3——n，行号比j大2；<br />
……<br />
行号起点随层号i增加而增加，层内其它各行的行号又随层内序号j增加而增加，由于编号起始为1，i层第j个数据的列下标为i-1+j。<br />
综合以上分析,i层第 j个数据对应的数组元素是a[i-1+j][j]。<br />
main( )<br />
{int i,j,a[100][100],n,k;<br />
input(n);<br />
k=1;<br />
for(i=1;i&lt;=n;i=i+1)<br />
for( j=1;j&lt;=n+1-i;j=j+1)<br />
{a[i-1+j][j]=k;<br />
k=k+1;}<br />
for(i=1;i&lt;=n;i=i+1)<br />
{printf( “换行符”);<br />
for( j=1;j&lt;=i;j=j+1)<br />
print(a[i][j]);<br />
}<br />
}</p>
<p><span style="color: #0000ff;"><strong>递归</strong></span><br />
递归算法是一个模块（函数、过程）除了可调用其它模  块（函数、过程）外，还可以直接或间接地调用自身的算法。<br />
递归是一种比迭代循环更强、更好用的循环结构。<br />
只需要找出递归关系和最小问题的解。<br />
递归方法只需少量的步骤就可描述出解题过程所需要的多次重复计算，大大地减少了算法的代码量。</p>
<p>递归的关键在于找出递归方程式和递归终止条件.<br />
递归定义：使问题向边界条件转化的规则。递归定义必须能使问题越来越简单。递归边界条件：也就是所描述问题的最简单情况，它本身不再使用递归的定义。<br />
<strong></strong></p>
<p>递归算法解题通常有三个步骤：</p>
<p>1）分析问题、寻找递归：找出大规模问题与小规模问题的关系，这样通过递归使问题的规模逐渐变小。</p>
<p>2）设置边界、控制递归：找出停止条件，即算法可解的最小规模问题。</p>
<p>3）设计函数、确定参数：和其它算法模块一样设计函数体中的操作及相关参数。</p>
<p><strong><br />
递归与循环的比较 </strong><br />
递归与循环都是解决“重复操作”的机制。<br />
递归使一些复杂的问题处理起来简单明了。<br />
就效率而言，递归算法的实现往往要比迭代算法耗费更多的时间（调用和返回均需要额外的时间）与存贮空间（用来保存不同次调用情况下变量的当前值的栈栈空间），也限制了递归的深度。<br />
每个迭代算法原则上总可以转换成与它等价的递归算法；反之不然 。<br />
递归的层次是可以控制的，而循环嵌套的层次只能是固定的，因此递归是比循环更灵活的重复操作的机制。</p>
<p>递归是一种强有力的算法设计方法。递归是一种比循环更强、更好用的实现“重复操作”的机制。因为递归不需要编程者（算法设计者）自己构造“循环不变式”，而只需要找出递归关系和最小问题的解。递归在很多算法策略中得以运用，如：分治策略、动态规划、图的搜索等算法策略。</p>
<p><strong>优缺点：</strong></p>
<p>循环效率更高，递归容易理解是大家普遍的观点。尽管两种想法在时间复杂度和空间复杂度上是等价的。但递归的有一个弱势：函数调用开销如参数传递和堆栈之类的开销，会导致在层次过深的时候，系统崩溃。递归是用栈机制实现的（c++），每深入一层，都要占去一块栈数据区域，对嵌套层数深的一些算法，递归会力不从心，空间上会以内存崩溃而告终，而且递归也带来了大量的函数调用，这也有许多额外的时间开销。所以在深度大时，它的时空性就不好了。循环的运行时间只因循环次数增加而增加，没什么额外开销。空间上没有什么增加。</p>
<p><strong>相互转化：</strong></p>
<p>可以相互转化，但是循环转化成递归更容易想；一般尾递归（即最后一句话进行递归）和单向递归（函数中只有一个递归调用地方）都可以用循环来避免递归。更复杂的情况则要引入栈来进行压栈出栈来改造成非递归，这个栈不一定要严格引入栈数据结构，只需要有这样的思路，用数组什么的就可以。</p>
<p><img src="file:///C:/Users/HuaiU/AppData/Local/Temp/moz-screenshot.png" alt="" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.javachen.com/2010/02/circle-and-recurrence/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>算法复杂度分析</title>
		<link>http://www.javachen.com/2010/02/the-analysis-of-algorithm-complexity/</link>
		<comments>http://www.javachen.com/2010/02/the-analysis-of-algorithm-complexity/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 06:08:10 +0000</pubDate>
		<dc:creator>JavaChen</dc:creator>
				<category><![CDATA[C/Algorithm]]></category>

		<guid isPermaLink="false">http://www.javachen.com/?p=999</guid>
		<description><![CDATA[算法分为时间复杂度和空间复杂度。时间复杂度是度量算法执行的时间长短；而空间复杂度是度量算法所需存储空间的大小。 一般情况下，算法的基本操作重复执行的次数是模块n的某一个函数f（n），因此，算法的时间复杂度记做：T（n）=O（f（n））　　分析：随着模块n的增大，算法执行的时间的增长率和f（n）的增长率成正比，所以f（n）越小，算法的时间复杂度越低，算法的效率越高。当输入量n逐渐加大时，时间复杂性的极限情形称为算法的“渐近时间复杂性”。 常见的时间复杂度按数量级递增排列,依次为:常数阶0(1)、对数阶0(log2n)、线性阶0(n)、线性对数阶0(nlog2n)、平方阶0(n2)、立方阶0(n3)、k次方阶0(nk)、指数阶0(2n)。 常见的算法时间复杂度由小到大依次为： Ο(1)＜Ο(log2n)＜Ο(n)＜Ο(nlog2n)＜Ο(n2)＜Ο(n3)＜…＜Ο(2n)＜Ο(n!) Ο(1)表示基本语句的执行次数是一个常数，一般来说，只要算法中不存在循环语句，其时间复杂度就是Ο(1)。Ο(log2n)、Ο(n)、Ο(nlog2n)、 Ο(n2)和Ο(n3)称为多项式时间，而Ο(2n)和Ο(n!)称为指数时间。计算机科学家普遍认为前者是有效算法，把这类问题称为P类问题，而把后者称为NP问题。 以下可以简单的计算算法的时间复杂度： O(1) Temp=i;i=j;j=temp; 以上三条单个语句的频度均为1，该程序段的执行时间是一个与问题规模n无关的常数。算法的时间复杂度为常数阶，记作T(n)=O(1)。如果算法的执行时间不随着问题规模n的增加而增长，即使算法中有上千条语句，其执行时间也不过是一个较大的常数。此类算法的时间复杂度是O(1)。 O(n^2) 2.1. 交换i和j的内容 sum=0；                 （一次） for(i=1;i&#60;=n;i++)       （n次 ） for(j=1;j&#60;=n;j++) （n^2次 ） sum++；       （n^2次 ） 解：T(n)=2n^2+n+1 =O(n^2) 2.2. for (i=1;i&#60;n;i++) { y=y+1;         ① for (j=0;j&#60;=(2*n);j++) x++;        ② } 解： 语句1的频度是n-1 语句2的频度是(n-1)*(2n+1)=2n^2-n-1 f(n)=2n^2-n-1+(n-1)=2n^2-2 该程序的时间复杂度T(n)=O(n^2). O(n) 2.3. a=0; b=1;                      ① for (i=1;i&#60;=n;i++) ② { s=a+b;　　　　③ b=a;　　　　　④ a=s;　　　　　⑤ [...]]]></description>
			<content:encoded><![CDATA[<p>算法分为时间复杂度和空间复杂度。时间复杂度是度量算法执行的时间长短；而空间复杂度是度量算法所需存储空间的大小。</p>
<p>一般情况下，算法的基本操作重复执行的次数是模块n的某一个函数f（n），因此，算法的时间复杂度记做：T（n）=O（f（n））　　分析：随着模块n的增大，算法执行的时间的增长率和f（n）的增长率成正比，所以f（n）越小，算法的时间复杂度越低，算法的效率越高。当输入量n逐渐加大时，时间复杂性的极限情形称为算法的“渐近时间复杂性”。<br />
<span id="more-999"></span>常见的时间复杂度按数量级递增排列,依次为:常数阶0(1)、对数阶0(log<sub>2</sub>n)、线性阶0(n)、线性对数阶0(nlog<sub>2</sub>n)、平方阶0(n<sup>2</sup>)、立方阶0(n<sup>3</sup>)、k次方阶0(n<sup>k</sup>)、指数阶0(2<sup>n</sup>)。<br />
常见的算法时间复杂度由小到大依次为：</p>
<p><span style="color: #0000ff;">Ο(1)＜Ο(log2n)＜Ο(n)＜Ο(nlog2n)＜Ο(n2)＜Ο(n3)＜…＜Ο(2n)＜Ο(n!)</span></p>
<p>Ο(1)表示基本语句的执行次数是一个常数，一般来说，只要算法中不存在循环语句，其时间复杂度就是Ο(1)。Ο(log2n)、Ο(n)、Ο(nlog2n)、 Ο(n2)和Ο(n3)称为多项式时间，而Ο(2n)和Ο(n!)称为指数时间。计算机科学家普遍认为前者是有效算法，把这类问题称为P类问题，而把后者称为NP问题。</p>
<p>以下可以简单的计算算法的时间复杂度：</p>
<p>O(1)</p>
<p>Temp=i;i=j;j=temp;</p>
<p>以上三条单个语句的频度均为1，该程序段的执行时间是一个与问题规模n无关的常数。算法的时间复杂度为常数阶，记作T(n)=O(1)。如果算法的执行时间不随着问题规模n的增加而增长，即使算法中有上千条语句，其执行时间也不过是一个较大的常数。此类算法的时间复杂度是O(1)。</p>
<p>O(n^2)</p>
<p>2.1. 交换i和j的内容<br />
sum=0；                 （一次）<br />
for(i=1;i&lt;=n;i++)       （n次 ）<br />
for(j=1;j&lt;=n;j++) （n^2次 ）<br />
sum++；       （n^2次 ）<br />
解：T(n)=2n^2+n+1 =O(n^2)</p>
<p>2.2.<br />
for (i=1;i&lt;n;i++)<br />
{<br />
y=y+1;         ①<br />
for (j=0;j&lt;=(2*n);j++)<br />
x++;        ②<br />
}<br />
解： 语句1的频度是n-1<br />
语句2的频度是(n-1)*(2n+1)=2n^2-n-1<br />
f(n)=2n^2-n-1+(n-1)=2n^2-2<br />
该程序的时间复杂度T(n)=O(n^2).</p>
<p>O(n)</p>
<p>2.3.<br />
a=0;<br />
b=1;                      ①<br />
for (i=1;i&lt;=n;i++) ②<br />
{<br />
s=a+b;　　　　③<br />
b=a;　　　　　④<br />
a=s;　　　　　⑤<br />
}<br />
解： 语句1的频度：2,<br />
语句2的频度： n,<br />
语句3的频度： n-1,<br />
语句4的频度：n-1,<br />
语句5的频度：n-1,<br />
T(n)=2+n+3(n-1)=4n-1=O(n).</p>
<p>O(log2n )</p>
<p>2.4.<br />
i=1;       ①<br />
while (i&lt;=n)<br />
i=i*2; ②<br />
解： 语句1的频度是1,<br />
设语句2的频度是f(n),   则：2^f(n)&lt;=n;f(n)&lt;=log2n<br />
取最大值f(n)= log2n,<br />
T(n)=O(log2n )</p>
<p>O(n^3)</p>
<p>2.5.<br />
for(i=0;i&lt;n;i++)<br />
{<br />
for(j=0;j&lt;i;j++)<br />
{<br />
for(k=0;k&lt;j;k++)<br />
x=x+2;<br />
}<br />
}<br />
解：当i=m, j=k的时候,内层循环的次数为k当i=m时, j 可以取 0,1,&#8230;,m-1 , 所以这里最内循环共进行了0+1+&#8230;+m-1=(m-1)m/2次所以,i从0取到n, 则循环共进行了: 0+(1-1)*1/2+&#8230;+(n-1)n/2=n(n+1)(n-1)/6所以时间复杂度为O(n^3).</p>
<p>我们还应该区分算法的最坏情况的行为和期望行为。如快速排序的最 坏情况运行时间是 O(n^2)，但期望时间是 O(nlogn)。通过每次都仔细地选择基准值，我们有可能把平方情况 (即O(n^2)情况)的概率减小到几乎等于 0。在实际中，精心实现的快速排序一般都能以 (O(nlogn)时间运行。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javachen.com/2010/02/the-analysis-of-algorithm-complexity/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What is Base64?</title>
		<link>http://www.javachen.com/2010/01/what-is-base64/</link>
		<comments>http://www.javachen.com/2010/01/what-is-base64/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 10:00:46 +0000</pubDate>
		<dc:creator>JavaChen</dc:creator>
				<category><![CDATA[C/Algorithm]]></category>
		<category><![CDATA[Base64]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[MIME]]></category>

		<guid isPermaLink="false">http://www.javachen.com/?p=912</guid>
		<description><![CDATA[这是一篇普及互联网术语的文章。每天呆在互联网上，发现呆的时间越长，发现自己不知道的东西越多。互联网上有太多的知识，虽然我们不可能一下子了解透彻， 但是遇到一个就有必要去了解其相关的知识或是原理，这样以后再见到他就不会觉得陌生了。 Base64是一种使用64基的位置计数法。它使用2的最大次方来代表仅可打印的ASCII 字符。这使它可用来作为电子邮件的传输编码。在Base64中的变量使用字符A-Z、a-z和0-9 ，这样共有62个字符，用来作为开始的64个数字，最后两个用来作为数字的符号在不同的系统中而不同。例如：&#8221;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/&#8220;。 base64是一种将二进制的01序列转化成ASCII字符的编码方法。编码后的文本或者二进制消息，就可以运用SMTP等只支持ASCII字符的协议传送了。Base64一般被认为会平均增加33%的报文长度，而且，经过编码的消息对于人类来说是不可读的。 在MIME格式的电子邮件中，base64可以用来将binary的字节序列数据编码成ASCII字符序列构成的文本。 算法详解 Base64要求把每三个8Bit的字节转换为四个6Bit的字节（3*8 = 4*6 = 24），然后把6Bit再添两位高位0，组成四个8Bit的字节，也就是说，转换后的字符串理论上将要比原来的长1/3。 转换的时候，将三个byte的数据，先后放入一个24bit的缓冲区中，先来的byte占高位。数据不足3byte的话，于缓冲区中剩下的bit用 0补足。然后，每次取出6（因为26 = 64）个bit，按照其值选择ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/中的字符作为编码后的输出。不断进行，直到全部输入数据转换完成。 如果最后剩下两个输入数据，在编码结果后加1个“=”；如果最后剩下一个输入数据，编码结果后加2个“=”；如果没有剩下任何数据，就什么都不要加，这样才可以保证资料还原的正确性。 注意：根据RFC822规定，每76个字符，还需要加上一个回车换行。 转换后，我们用一个码表来得到我们想要的字符串（也就是最终的Base64编码），这个表是这样的：（摘自RFC2045） Table 1: The Base64 Alphabet Value Encoding  Value Encoding  Value Encoding  Value Encoding 0 A            17 R            34 i            51 z 1 B            18 S            35 j            52 0 2 C            19 T            36 k            53 1 3 D            20 U            37 l            54 2 4 E            21 V            38 m            55 3 [...]]]></description>
			<content:encoded><![CDATA[<p>这是一篇普及互联网术语的文章。每天呆在互联网上，发现呆的时间越长，发现自己不知道的东西越多。互联网上有太多的知识，虽然我们不可能一下子了解透彻， 但是遇到一个就有必要去了解其相关的知识或是原理，这样以后再见到他就不会觉得陌生了。</p>
<p><span style="color: #ff00ff;">Base64是一种使用64基的位置计数法</span>。它使用2的最大次方来代表仅可打印的ASCII 字符。这使它可用来作为电子邮件的传输编码。在Base64中的变量使用字符A-Z、a-z和0-9 ，这样共有62个字符，用来作为开始的64个数字，最后两个用来作为数字的符号在不同的系统中而不同。例如：&#8221;<span style="color: #0000ff;">ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/</span>&#8220;。<br />
<span style="color: #ff00ff;">base64是一种将二进制的01序列转化成ASCII字符的编码方法</span>。编码后的文本或者二进制消息，就可以运用SMTP等只支持ASCII字符的协议传送了。Base64一般被认为会平均增加<span style="color: #0000ff;">33%</span>的报文长度，而且，经过编码的消息对于人类来说是不可读的。<br />
在<a href="http://www.javachen.com/2010/01/what-is-mime%EF%BC%9F/" target="_blank">MIME</a>格式的电子邮件中，base64可以用来将binary的字节序列数据编码成ASCII字符序列构成的文本。<span id="more-912"></span></p>
<p>算法详解<br />
<span style="color: #0000ff;">Base64要求把每三个8Bit的字节转换为四个6Bit的字节（3*8 = 4*6 =  24），然后把6Bit再添两位高位0，组成四个8Bit的字节，也就是说，转换后的字符串理论上将要比原来的长1/3。</span><br />
转换的时候，将三个byte的数据，先后放入一个24bit的缓冲区中，先来的byte占高位。数据不足3byte的话，于缓冲区中剩下的bit用 0补足。然后，每次取出6（因为26 = 64）个bit，按照其值选择ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/中的字符作为编码后的输出。不断进行，直到全部输入数据转换完成。<br />
如果最后剩下两个输入数据，在编码结果后加1个“=”；如果最后剩下一个输入数据，编码结果后加2个“=”；如果没有剩下任何数据，就什么都不要加，这样才可以保证资料还原的正确性。</p>
<p><span style="color: #ff0000;">注意：根据RFC822规定，每76个字符，还需要加上一个回车换行。</span></p>
<p>转换后，我们用一个码表来得到我们想要的字符串（也就是最终的Base64编码），这个表是这样的：（摘自RFC2045）<br />
Table 1: The Base64 Alphabet</p>
<p>Value Encoding  Value Encoding  Value Encoding  Value Encoding<br />
0 A            17 R            34 i            51 z<br />
1 B            18 S            35 j            52 0<br />
2 C            19 T            36 k            53 1<br />
3 D            20 U            37 l            54 2<br />
4 E            21 V            38 m            55 3<br />
5 F            22 W            39 n            56 4<br />
6 G            23 X            40 o            57 5<br />
7 H            24 Y            41 p            58 6<br />
8 I            25 Z            42 q            59 7<br />
9 J            26 a            43 r            60 8<br />
10 K            27 b            44 s            61 9<br />
11 L            28 c            45 t            62 +<br />
12 M            29 d            46 u            63 /<br />
13 N            30 e            47 v<br />
14 O            31 f            48 w         (pad) =<br />
15 P            32 g            49 x<br />
16 Q            33 h            50 y</p>
<p>这也是Base64名称的由来，而Base64编码的结果不是根据算法把编码变为高两位是0而低6为代表数据，而是变为了上表的形式， 如”A”就有7位，而”a”就只有6位。表中，编码的编号对应的是得出的新字节的十进制值。</p>
<p>用更接近于编程的思维来说，编码的过程是这样的：<br />
第一个字符通过右移2位获得第一个目标字符的Base64表位置，根据这个数值取到表上 相应的字符，就是第一个目标字符。<br />
然后将第一个字符左移4位加上第二个字符右移4位，即获得第二个目标字符。<br />
再将第二个字符左移2位加上 第三个字符右移6位，获得第三个目标字符。<br />
最后取第三个字符的右6位即获得第四个目标字符。</p>
<p>在以上的每一个步骤之后，再把结果与 0x3F 进行 AND 位操作，就可以得到编码后的字符了。</p>
<p>在JAVA中要实现Base64的编码和解码是非常容易的，因为JDK中已经有提供有现成的类：<br />
    编码：<br />
String src =&#8221;BASE64编码测试&#8221;;<br />
sun.misc.BASE64Encoder en = new sun.misc.BASE64Encoder();<br />
String encodeStr = en.encode(src.getBytes());<br />
注意：当encodeStr的长度超过76时，会包含有回车和换行符</p>
<p>    解码：<br />
sun.misc.BASE64Decoder dec = new sun.misc.BASE64Decoder();<br />
byte[] data = dec.decodeBuffer(decodeStr);</p>
<p>最近在研究Xmappr项目时候，发现了其对Base64编码的一种实现：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">/*
 * This software is released under the BSD license. Full license available at http://xmappr.googlecode.com
 *
 * Copyright (c) 2008, 2009, Peter Knego &amp; Xmappr contributors
 * All rights reserved.
 */</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">xmappr.org.xmappr.converters</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * Utility class implementing Base64 decoder/encoder.
 */</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Base64 <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">char</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> base64code <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/&quot;</span>
			.<span style="color: #006633;">toCharArray</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// 初始化数组</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> nibbles <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">128</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">static</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #008000; font-style: italic; font-weight: bold;">/**
		 * The Base64 Alphabet
			Value Encoding 
			0 A 17 R 34 i 51 z
			1 B 18 S 35 j 52 0
			2 C 19 T 36 k 53 1
			3 D 20 U 37 l 54 2
			4 E 21 V 38 m 55 3
			5 F 22 W 39 n 56 4
			6 G 23 X 40 o 57 5
			7 H 24 Y 41 p 58 6
			8 I 25 Z 42 q 59 7
			9 J 26 a 43 r 60 8
			10 K 27 b 44 s 61 9
			11 L 28 c 45 t 62 +
			12 M 29 d 46 u 63 /
			13 N 30 e 47 v (pad) =
			14 O 31 f 48 w
			15 P 32 g 49 x
			16 Q 33 h 50 y 
		 */</span>
		<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> nibbles.<span style="color: #006633;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
			nibbles<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
		<span style="color: #666666; font-style: italic;">//将0-63存入nibbles['A']-nibbles['=']，生成上面的Base64位字母表</span>
		<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">64</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
			nibbles<span style="color: #009900;">&#91;</span>base64code<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span> i<span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399;">String</span> encode<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> input<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> encode<span style="color: #009900;">&#40;</span>input, <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399;">String</span> encode<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> input, <span style="color: #000066; font-weight: bold;">int</span> lineLength<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
		<span style="color: #000066; font-weight: bold;">int</span> ilen <span style="color: #339933;">=</span> input.<span style="color: #006633;">length</span><span style="color: #339933;">;</span>
		<span style="color: #666666; font-style: italic;">// 计算加入多少个等于号到编码后面</span>
		<span style="color: #000066; font-weight: bold;">int</span> padding <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">3</span> <span style="color: #339933;">-</span> <span style="color: #009900;">&#40;</span>ilen <span style="color: #339933;">%</span> <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">%</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000066; font-weight: bold;">char</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> encoded <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">char</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">4</span> <span style="color: #339933;">*</span> <span style="color: #009900;">&#40;</span>ilen <span style="color: #339933;">+</span> padding<span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">int</span> c <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">int</span> j, j0, j1, j2<span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">&lt;</span> ilen<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			j0 <span style="color: #339933;">=</span> input<span style="color: #009900;">&#91;</span>i<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			j1 <span style="color: #339933;">=</span> i <span style="color: #339933;">&lt;</span> ilen <span style="color: #339933;">?</span> input<span style="color: #009900;">&#91;</span>i<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
			j2 <span style="color: #339933;">=</span> i <span style="color: #339933;">&lt;</span> ilen <span style="color: #339933;">?</span> input<span style="color: #009900;">&#91;</span>i<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
			j <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>j0 <span style="color: #339933;">&lt;&lt;</span> <span style="color: #cc66cc;">16</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>j1 <span style="color: #339933;">&lt;&lt;</span> <span style="color: #cc66cc;">8</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> j2<span style="color: #339933;">;</span>
&nbsp;
			encoded<span style="color: #009900;">&#91;</span>c<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> base64code<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#40;</span>j <span style="color: #339933;">&gt;&gt;</span> <span style="color: #cc66cc;">18</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> 0x3f<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			encoded<span style="color: #009900;">&#91;</span>c<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> base64code<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#40;</span>j <span style="color: #339933;">&gt;&gt;</span> <span style="color: #cc66cc;">12</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> 0x3f<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			encoded<span style="color: #009900;">&#91;</span>c<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> base64code<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#40;</span>j <span style="color: #339933;">&gt;&gt;</span> <span style="color: #cc66cc;">6</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span> 0x3f<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			encoded<span style="color: #009900;">&#91;</span>c<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> base64code<span style="color: #009900;">&#91;</span>j <span style="color: #339933;">&amp;</span> 0x3f<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// replace encoded padding nulls with &quot;=&quot;</span>
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>padding <span style="color: #339933;">==</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			encoded<span style="color: #009900;">&#91;</span>encoded.<span style="color: #006633;">length</span> <span style="color: #339933;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'='</span><span style="color: #339933;">;</span>
			encoded<span style="color: #009900;">&#91;</span>encoded.<span style="color: #006633;">length</span> <span style="color: #339933;">-</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'='</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>padding <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			encoded<span style="color: #009900;">&#91;</span>encoded.<span style="color: #006633;">length</span> <span style="color: #339933;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'='</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">return</span> lineLength <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span> <span style="color: #339933;">?</span> splitLines<span style="color: #009900;">&#40;</span>encoded, lineLength<span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #003399;">String</span>
				.<span style="color: #006633;">valueOf</span><span style="color: #009900;">&#40;</span>encoded<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399;">String</span> splitLines<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">char</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> chars, <span style="color: #000066; font-weight: bold;">int</span> lineLength<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		StringBuilder lines <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> StringBuilder<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> chars.<span style="color: #006633;">length</span><span style="color: #339933;">;</span> i <span style="color: #339933;">+=</span> lineLength<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			lines.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>chars, i, <span style="color: #003399;">Math</span>.<span style="color: #006633;">min</span><span style="color: #009900;">&#40;</span>chars.<span style="color: #006633;">length</span> <span style="color: #339933;">-</span> i, lineLength<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
					.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #000000; font-weight: bold;">return</span> lines.<span style="color: #006633;">delete</span><span style="color: #009900;">&#40;</span>lines.<span style="color: #006633;">length</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #cc66cc;">2</span>, lines.<span style="color: #006633;">length</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> decode<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> decode<span style="color: #009900;">&#40;</span>data.<span style="color: #006633;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">toCharArray</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> decode<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">char</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> chars<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
		<span style="color: #000066; font-weight: bold;">int</span> charCount <span style="color: #339933;">=</span> chars.<span style="color: #006633;">length</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// remove newlines from character count</span>
		<span style="color: #000066; font-weight: bold;">int</span> a <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span>a <span style="color: #339933;">&lt;</span> chars.<span style="color: #006633;">length</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>chars<span style="color: #009900;">&#91;</span>a<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'<span style="color: #000099; font-weight: bold;">\r</span>'</span> <span style="color: #339933;">||</span> chars<span style="color: #009900;">&#91;</span>a<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: #009900;">&#41;</span>
				charCount<span style="color: #339933;">--;</span>
			a<span style="color: #339933;">++;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// check the char count</span>
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>charCount <span style="color: #339933;">%</span> <span style="color: #cc66cc;">4</span> <span style="color: #339933;">!=</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">IllegalArgumentException</span><span style="color: #009900;">&#40;</span>
					<span style="color: #0000ff;">&quot;Length of Base64 encoded input string is not a multiple of 4.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// count padding characters '='</span>
		<span style="color: #000066; font-weight: bold;">int</span> padCount <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span>chars<span style="color: #009900;">&#91;</span>chars.<span style="color: #006633;">length</span> <span style="color: #339933;">-</span> <span style="color: #cc66cc;">1</span> <span style="color: #339933;">-</span> padCount<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'='</span><span style="color: #009900;">&#41;</span>
			padCount<span style="color: #339933;">++;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// create the output byte array, take padding into account</span>
		<span style="color: #000066; font-weight: bold;">int</span> olen <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">3</span> <span style="color: #339933;">*</span> charCount<span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #cc66cc;">4</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> padCount<span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> out <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span>olen<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">int</span> o <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">int</span> c <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> nibbleBlock <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">char</span> currentChar<span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">byte</span> currentNibble<span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">&lt;</span> chars.<span style="color: #006633;">length</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #666666; font-style: italic;">// read four character into temporary storage (and skip newlines)</span>
			c <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
			<span style="color: #000000; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span>c <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">4</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				currentChar <span style="color: #339933;">=</span> chars<span style="color: #009900;">&#91;</span>i<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
				<span style="color: #666666; font-style: italic;">// skip newline and padding characters</span>
				<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>currentChar <span style="color: #339933;">!=</span> <span style="color: #0000ff;">'<span style="color: #000099; font-weight: bold;">\r</span>'</span> <span style="color: #339933;">&amp;&amp;</span> currentChar <span style="color: #339933;">!=</span> <span style="color: #0000ff;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
					<span style="color: #666666; font-style: italic;">// nibble conversion table only holds 128 characters</span>
					<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>currentChar <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">127</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
						<span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">IllegalArgumentException</span><span style="color: #009900;">&#40;</span>
								<span style="color: #0000ff;">&quot;Illegal character in Base64 encoded data.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
					<span style="color: #009900;">&#125;</span>
&nbsp;
					currentNibble <span style="color: #339933;">=</span> currentChar <span style="color: #339933;">!=</span> <span style="color: #0000ff;">'='</span> <span style="color: #339933;">?</span> nibbles<span style="color: #009900;">&#91;</span>currentChar<span style="color: #009900;">&#93;</span>
							<span style="color: #339933;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
					<span style="color: #666666; font-style: italic;">// char does not exist (==-1) in conversion table</span>
					<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>currentNibble <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
						<span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">IllegalArgumentException</span><span style="color: #009900;">&#40;</span>
								<span style="color: #0000ff;">&quot;Illegal character in Base64 encoded data.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
					<span style="color: #009900;">&#125;</span>
					nibbleBlock<span style="color: #009900;">&#91;</span>c<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> currentNibble<span style="color: #339933;">;</span>
				<span style="color: #009900;">&#125;</span>
			<span style="color: #009900;">&#125;</span>
&nbsp;
			<span style="color: #666666; font-style: italic;">// convert four nibbles into three bytes (4x 6-bit nibbles = 3</span>
			<span style="color: #666666; font-style: italic;">// bytes)</span>
			out<span style="color: #009900;">&#91;</span>o<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>nibbleBlock<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">|</span> <span style="color: #009900;">&#40;</span>nibbleBlock<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;&gt;&gt;</span> <span style="color: #cc66cc;">4</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>o <span style="color: #339933;">&lt;</span> olen<span style="color: #009900;">&#41;</span>
				out<span style="color: #009900;">&#91;</span>o<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>nibbleBlock<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xf<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;&lt;</span> <span style="color: #cc66cc;">4</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">|</span> <span style="color: #009900;">&#40;</span>nibbleBlock<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;&gt;&gt;</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>o <span style="color: #339933;">&lt;</span> olen<span style="color: #009900;">&#41;</span>
				out<span style="color: #009900;">&#91;</span>o<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>nibbleBlock<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;&lt;</span> <span style="color: #cc66cc;">6</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">|</span> nibbleBlock<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">return</span> out<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p><span style="color: #ff00ff;">网上有很多介绍关于base64编码的例子，典型的是用“张3”举例得到的编码是“1iUz”，可是我用上面的代码得到的结果是：“1MUz”，两种结果相差了一位，很是奇怪。这是为什么？！</span></p>
<h2>UTF-7</h2>
<p><a title="UTF-7" href="http://zh.wikipedia.org/zh-cn/UTF-7">UTF-7</a> 是一个修改的Base64（<strong>Modified Base64</strong>）。主要是将<a title="UTF-16" href="http://zh.wikipedia.org/zh-cn/UTF-16">UTF-16</a>的数 据，用Base64的方法编码为可打印的 <a title="ASCII" href="http://zh.wikipedia.org/zh-cn/ASCII">ASCII</a> 字符序列。目的是传输 Unicode  数据。主要的区别在于不用等号&#8221;=&#8221;补余，因为该字符通常需要大量的转译。</p>
<h2>在URL中的应用</h2>
<p>Base64编码可用于在<a title="HTTP" href="http://zh.wikipedia.org/zh-cn/HTTP">HTTP</a>环境下传递较长的标识信息。例如，在<a title="Java" href="http://zh.wikipedia.org/zh-cn/Java">Java</a><a title="持久化（尚未撰写）" href="http://zh.wikipedia.org/w/index.php?title=%E6%8C%81%E4%B9%85%E5%8C%96&amp;action=edit&amp;redlink=1">持久化</a>系统<a title="Hibernate (Java)（尚未撰写）" href="http://zh.wikipedia.org/w/index.php?title=Hibernate_%28Java%29&amp;action=edit&amp;redlink=1">Hibernate</a>中，就采用了Base64来将一 个较长的唯一标识符（一般为128-bit的<a title="UUID" href="http://zh.wikipedia.org/zh-cn/UUID">UUID</a>）编码为一个字符串，用作HTTP表单和HTTP GET <a title="URL" href="http://zh.wikipedia.org/zh-cn/URL">URL</a>中 的参数。在其他应用程序中，也常常需要把二进制数据编码为适合放在URL（包括隐藏表单域）中的形式。此时，采用Base64编码不仅比较简短，同时也具 有不可读性，即所编码的数据不会被人用肉眼所直接看到。</p>
<p>然而，标准的Base64并不适合直接放在URL里传输，因为URL编码器会把标准Base64中的“/”和“+”字符变为形如“%XX”的形式， 而这些“%”号在存入数据库时还需要再进行转换，因为<a title="ANSI" href="http://zh.wikipedia.org/zh-cn/ANSI">ANSI</a> <a title="SQL" href="http://zh.wikipedia.org/zh-cn/SQL">SQL</a>中已将“%”号用作通配 符。</p>
<p>为解决此问题，可采用一种<strong>用于URL的改进Base64</strong>编码，它不在末尾填充&#8217;='号，并将标准Base64中的“+”和“/”分别 改成了“*”和“-”，这样就免去了在URL编解码和数据库存储时所要作的转换，避免了编码信息长度在此过程中的增加，并统一了数据库、表单等处对象标识 符的格式。</p>
<p>另有一种<strong>用于正则表达式的改进Base64</strong>变种，它将“+”和“/”改成了“!”和“-”，因为“+”，“*”以及前面在IRCu中 用到的“[”和“]”在<a title="正则表达式" href="http://zh.wikipedia.org/zh-cn/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F">正则表达式</a>中都可能具有特殊含义。</p>
<p>此外还有一些变种，它们将“+/”改为“_-”或“._”（用作编程语言中的标识符名称）或“.-”（用于<a title="XML" href="http://zh.wikipedia.org/zh-cn/XML">XML</a>中的<em>Nmtoken</em>） 甚至“_:”（用于XML中的<em>Name</em>）。</p>
<p>关于 Base64可以参照网上另一篇文章：<a href="http://www.5dmail.net/html/2004-1-30/200413084348.htm" target="_blank">浅谈Base64编码</a></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.javachen.com/2010/01/what-is-base64/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>海盗分金的博弈问题</title>
		<link>http://www.javachen.com/2010/01/pirates-share-gold/</link>
		<comments>http://www.javachen.com/2010/01/pirates-share-gold/#comments</comments>
		<pubDate>Sat, 16 Jan 2010 17:20:38 +0000</pubDate>
		<dc:creator>JavaChen</dc:creator>
				<category><![CDATA[C/Algorithm]]></category>
		<category><![CDATA[GameTheory]]></category>

		<guid isPermaLink="false">http://www.javachen.com/?p=850</guid>
		<description><![CDATA[5个海盗抢到了100颗宝石，每一颗都一样的大小和价值连城。 他们决定这么分： 1。抽签决定自己的号码（1，2，3，4，5） 2。首先，由1号提出分配方案，然后大家5人进行表决，当且超过半数或半数的人同意时，按照他的提案进行分配，否则将被扔入大海喂鲨鱼。 3。如果1号死后，再由2号提出分配方案，然后大家4人进行表决，当且仅当半数和超过半数的人同意时，按照他的提案进行分配，否则将被扔入大海喂鲨鱼。 4。以次类推&#8230;&#8230; 条件： 每个海盗都是很聪明的人，都能很理智的判断得失，从而做出选择。 问题： 第一个海盗提出怎样的分配方案才能够使自己的收益最大化 （如果在规则中加上下面一条会更加完善：海盗在自己的收益最大化的前提下乐意看到其他海盗被扔入大海喂鲨鱼） 使用倒推法： 一、假设1、2、3号已被扔入海中，则4号的方案必为100、0，且必定通过。故5号在得到3号1个宝石的情况下会坚决支持3号的方案。 二、3号的方案必为99、0、1，且必定通过。故4号在得到2号1个宝石的情况下会坚决支持2号的方案。 三、2号的方案必为99、0、1、0，且必定通过。2号不能把给4号的1个宝石给5号，5号未 必坚定地支持2号的方案，因为3号必定通过的方案也能让他得到1个宝石。为了万无一失的保命，2号必须选4号，且必定通过。故3号、5号在各得到1号1个 宝石的情况下会坚决支持1号的方案。 四、1号的方案必为98、0、1、0、1，且必定通过。 故答案是：98，0，1，0，1。 推理过程是这样的： 从后向前推，如果1至3号强盗都喂了鲨鱼，只剩4号和5号的话，5号一定投反对票让4号喂鲨鱼，以独吞全部金币。所以，4号惟有支持3号才能保命。 3号知道这一点，就会提出“100，0，0”的分配方案，对4号、5号一毛不拔而将全部金币归为已有，因为他知道4号一无所获但还是会投赞成票，再加上自己一票，他的方案即可通过。 不过，2号推知3号的方案，就会提出“98，0，1，1”的方案，即放弃3号，而给予4号和5号各一枚金币。由于该方案对于4号和5号来说比在3号分配时更为有利，他们将支持他而不希望他出局而由3号来分配。这样，2号将拿走98枚金币。 同样，2号的方案也会被1号所洞悉，1号并将提出（97，0，1，2，0）或 （97，0，1，0，2）的方案，即放弃2号，而给3号一枚金币，同时给4号（或5号）2枚金币。由于1号的这一方案对于3号和4号（或5号）来说，相比 2号分配时更优，他们将投1号的赞成票，再加上1号自己的票，1号的方案可获通过，97枚金币可轻松落入囊中。这无疑是1号能够获取最大收益的方案了！答 案是：1号强盗分给3号1枚金币，分给4号或5号强盗2枚，自己独得97枚。分配方案可写成（97，0，1，2，0）或（97，0，1，0，2）。 “海盗分金”其实是一个高度简化和抽象的模型，体现了博弈的思想。在“海盗分金”模型中，任何 “分配者”想让自己的方案获得通过的关键是事先考虑清楚“挑战者”的分配方案是什么，并用最小的代价获取最大收益，拉拢“挑战者”分配方案中最不得意的人 们。企业中的一把手，在搞内部人控制时，经常是抛开二号人物，而与会计和出纳们打得火热，就是因为公司里的小人物好收买。 1号看起来最有可能喂鲨鱼，但他牢牢地把握住先发优势，结果不但消除了死亡威胁，还收益最大。这不正是全球化过程中先进国家的先发优势吗？而5号，看起来最安全，没有死亡的威胁，甚至还能坐收渔人之利，却因不得不看别人脸色行事而只能分得一小杯羹。 不过，模型任意改变一个假设条件，最终结果都不一样。而现实世界远比模型复杂。 首先，现实中肯定不会是人人都“绝对理性”。回到“海盗分金”的模型中，只要3号、4号或5号中有一个人偏离了绝对聪明的假设，海盗1号无论怎么分都可能会被扔到海里去了。所以，1号首先要考虑的就是他的海盗兄弟们的聪明和理性究竟靠得住靠不住，否则先分者倒霉。 如果某人偏好看同伙被扔进海里喂鲨鱼。果真如此，1号自以为得意的方案岂不成了自掘坟墓！ 再就是俗话所说的“人心隔肚皮”。由于信息不对称，谎言和虚假承诺就大有用武之地，而阴谋也会像杂草般疯长，并借机获益。如果2号对3、4、5号大放烟幕弹，宣称对于1号所提出任何分配方案，他一定会再多加上一个金币给他们。这样，结果又当如何？ 通常，现实中人人都有自认的公平标准，因而时常会嘟嚷：“谁动了我的奶酪？”可以料想，一旦1 号所提方案和其所想的不符，就会有人大闹……当大家都闹起来的时候，1号能拿着97枚金币毫发无损、镇定自若地走出去吗？最大的可能就是，海盗们会要求修 改规则，然后重新分配。想一想二战前的希特勒德国吧！ 而假如由一次博弈变成重复博弈呢？比如，大家讲清楚下次再得100枚金币时，先由2号海盗来分……然后是3号……这颇有点像美国总统选举，轮流主政。说白了，其实是民主形式下的分赃制。 最可怕的是其他四人形成一个反1号的大联盟并制定出新规则：四人平分金币，将1号扔进大海……这就是阿Ｑ式的革命理想：高举平均主义的旗帜，将富人扔进死亡深渊…… 制度规范行为，理性战胜愚昧！ 如果假设变为，是10人分100枚金币，投票50%或以上才能通过，否则他将被扔入大海喂鲨鱼，依此类推。50%是问题的关键，海盗可以投自己的票。因此如果剩下两个人，无论什么方案都会被通过，即100，0。 往上推一步，3个人时，倒数第三个人知道如果出现两个人的情况，因此它会团结第一个人，给他一个金币 “往前推一步。现在加一个更凶猛的海盗P3。P1知道———P3知道他知道———如果P3的方 案被否决了，游戏就会只由P1和P2来继续，而P1就一枚金币也得不到。所以P3知道，只要给P1一枚金币，P1就会同意他的方案（当然，如果不给P1一 枚金币，P1反正什么也得不到，宁可投票让P3去喂鱼）。所以P3的最佳策略是：P1得1枚，P2什么也得不到，P3得99枚。 P4的情况差不多。他只要得两票就可以了，给P2一枚金币就可以让他投票赞同这个方案，因为在接下来P3的方案中P2什么也得不到。P5也是相同的推理方法只不过他要说服他的两个同伴，于是他给每一个在P4方案中什么也得不到的P1和P3一枚金币，自己留下98枚。 依此类推，最终P10的最佳方案是：他自己得96枚，给每一个在P9方案中什么也得不到的P2、P4、P6和P8一枚金币。 结果，“海盗分金”最后的结果是P1、P2、P3、P4、P5、P6、P7、P8、P9、P10各可以获得0、1、0、1、0、1、0、1、0、96枚金币。 在“海盗分金”中，任何“分配者”想让自己的方案获得通过的关键是，事先考虑清楚“挑战者”的分配方案是什么，并用最小的代价获取最大收益，拉拢“挑战者”分配方案中最不得意的人们。 真地是难以置信。P10看起来最有可能喂鲨鱼，但他牢牢地把握住先发优势，结果不但消除了死亡威胁，还获得了最大收益。而P1，看起来最安全，没有死亡的威胁，甚至还能坐收渔人之利，但却因不得不看别人脸色行事，结果连一小杯羹都无法分到，却只能够保住性命而已。 此类问题体现出的多方博弈情况下的生存哲学： 没有永恒的朋友，只有永恒的利益。 在临界点之下，以决策者的身份出场，冒最大的风险，得到最大的利益。 在接近临界点的地方，是收益分配最接近公平的地方。半数的人均匀地受益，另半数的人均匀地不受益。 [...]]]></description>
			<content:encoded><![CDATA[<p>5个海盗抢到了100颗宝石，每一颗都一样的大小和价值连城。<br />
他们决定这么分：<br />
1。抽签决定自己的号码（1，2，3，4，5）<br />
2。首先，由1号提出分配方案，然后大家5人进行表决，当且超过半数或半数的人同意时，按照他的提案进行分配，否则将被扔入大海喂鲨鱼。<br />
3。如果1号死后，再由2号提出分配方案，然后大家4人进行表决，当且仅当半数和超过半数的人同意时，按照他的提案进行分配，否则将被扔入大海喂鲨鱼。<br />
4。以次类推&#8230;&#8230; <span id="more-850"></span><br />
条件：<br />
每个海盗都是很聪明的人，都能很理智的判断得失，从而做出选择。<br />
问题：<br />
第一个海盗提出怎样的分配方案才能够使自己的收益最大化<br />
（如果在规则中加上下面一条会更加完善：海盗在自己的收益最大化的前提下乐意看到其他海盗被扔入大海喂鲨鱼）</p>
<p><strong>使用倒推法：</strong><br />
一、假设1、2、3号已被扔入海中，则4号的方案必为100、0，且必定通过。故5号在得到3号1个宝石的情况下会坚决支持3号的方案。<br />
二、3号的方案必为99、0、1，且必定通过。故4号在得到2号1个宝石的情况下会坚决支持2号的方案。<br />
三、2号的方案必为99、0、1、0，且必定通过。2号不能把给4号的1个宝石给5号，5号未 必坚定地支持2号的方案，因为3号必定通过的方案也能让他得到1个宝石。为了万无一失的保命，2号必须选4号，且必定通过。故3号、5号在各得到1号1个 宝石的情况下会坚决支持1号的方案。<br />
四、1号的方案必为98、0、1、0、1，且必定通过。<br />
故答案是：98，0，1，0，1。</p>
<p><strong>推理过程是这样的：</strong><br />
从后向前推，如果1至3号强盗都喂了鲨鱼，只剩4号和5号的话，5号一定投反对票让4号喂鲨鱼，以独吞全部金币。所以，4号惟有支持3号才能保命。<br />
3号知道这一点，就会提出“100，0，0”的分配方案，对4号、5号一毛不拔而将全部金币归为已有，因为他知道4号一无所获但还是会投赞成票，再加上自己一票，他的方案即可通过。<br />
不过，2号推知3号的方案，就会提出“98，0，1，1”的方案，即放弃3号，而给予4号和5号各一枚金币。由于该方案对于4号和5号来说比在3号分配时更为有利，他们将支持他而不希望他出局而由3号来分配。这样，2号将拿走98枚金币。<br />
同样，2号的方案也会被1号所洞悉，1号并将提出（97，0，1，2，0）或 （97，0，1，0，2）的方案，即放弃2号，而给3号一枚金币，同时给4号（或5号）2枚金币。由于1号的这一方案对于3号和4号（或5号）来说，相比 2号分配时更优，他们将投1号的赞成票，再加上1号自己的票，1号的方案可获通过，97枚金币可轻松落入囊中。这无疑是1号能够获取最大收益的方案了！答 案是：1号强盗分给3号1枚金币，分给4号或5号强盗2枚，自己独得97枚。分配方案可写成（97，0，1，2，0）或（97，0，1，0，2）。<br />
“海盗分金”其实是一个高度简化和抽象的模型，体现了博弈的思想。在“海盗分金”模型中，任何 “分配者”想让自己的方案获得通过的关键是事先考虑清楚“挑战者”的分配方案是什么，并用最小的代价获取最大收益，拉拢“挑战者”分配方案中最不得意的人 们。企业中的一把手，在搞内部人控制时，经常是抛开二号人物，而与会计和出纳们打得火热，就是因为公司里的小人物好收买。<br />
1号看起来最有可能喂鲨鱼，但他牢牢地把握住先发优势，结果不但消除了死亡威胁，还收益最大。这不正是全球化过程中先进国家的先发优势吗？而5号，看起来最安全，没有死亡的威胁，甚至还能坐收渔人之利，却因不得不看别人脸色行事而只能分得一小杯羹。<br />
不过，模型任意改变一个假设条件，最终结果都不一样。而现实世界远比模型复杂。<br />
首先，现实中肯定不会是人人都“绝对理性”。回到“海盗分金”的模型中，只要3号、4号或5号中有一个人偏离了绝对聪明的假设，海盗1号无论怎么分都可能会被扔到海里去了。所以，1号首先要考虑的就是他的海盗兄弟们的聪明和理性究竟靠得住靠不住，否则先分者倒霉。<br />
如果某人偏好看同伙被扔进海里喂鲨鱼。果真如此，1号自以为得意的方案岂不成了自掘坟墓！<br />
再就是俗话所说的“人心隔肚皮”。由于信息不对称，谎言和虚假承诺就大有用武之地，而阴谋也会像杂草般疯长，并借机获益。如果2号对3、4、5号大放烟幕弹，宣称对于1号所提出任何分配方案，他一定会再多加上一个金币给他们。这样，结果又当如何？<br />
通常，现实中人人都有自认的公平标准，因而时常会嘟嚷：“谁动了我的奶酪？”可以料想，一旦1 号所提方案和其所想的不符，就会有人大闹……当大家都闹起来的时候，1号能拿着97枚金币毫发无损、镇定自若地走出去吗？最大的可能就是，海盗们会要求修 改规则，然后重新分配。想一想二战前的希特勒德国吧！<br />
而假如由一次博弈变成重复博弈呢？比如，大家讲清楚下次再得100枚金币时，先由2号海盗来分……然后是3号……这颇有点像美国总统选举，轮流主政。说白了，其实是民主形式下的分赃制。<br />
最可怕的是其他四人形成一个反1号的大联盟并制定出新规则：四人平分金币，将1号扔进大海……这就是阿Ｑ式的革命理想：高举平均主义的旗帜，将富人扔进死亡深渊……<br />
制度规范行为，理性战胜愚昧！<br />
如果假设变为，是10人分100枚金币，投票50%或以上才能通过，否则他将被扔入大海喂鲨鱼，依此类推。50%是问题的关键，海盗可以投自己的票。因此如果剩下两个人，无论什么方案都会被通过，即100，0。<br />
往上推一步，3个人时，倒数第三个人知道如果出现两个人的情况，因此它会团结第一个人，给他一个金币<br />
“往前推一步。现在加一个更凶猛的海盗P3。P1知道———P3知道他知道———如果P3的方 案被否决了，游戏就会只由P1和P2来继续，而P1就一枚金币也得不到。所以P3知道，只要给P1一枚金币，P1就会同意他的方案（当然，如果不给P1一 枚金币，P1反正什么也得不到，宁可投票让P3去喂鱼）。所以P3的最佳策略是：P1得1枚，P2什么也得不到，P3得99枚。<br />
P4的情况差不多。他只要得两票就可以了，给P2一枚金币就可以让他投票赞同这个方案，因为在接下来P3的方案中P2什么也得不到。P5也是相同的推理方法只不过他要说服他的两个同伴，于是他给每一个在P4方案中什么也得不到的P1和P3一枚金币，自己留下98枚。<br />
依此类推，最终P10的最佳方案是：他自己得96枚，给每一个在P9方案中什么也得不到的P2、P4、P6和P8一枚金币。<br />
结果，“海盗分金”最后的结果是P1、P2、P3、P4、P5、P6、P7、P8、P9、P10各可以获得0、1、0、1、0、1、0、1、0、96枚金币。<br />
在“海盗分金”中，任何“分配者”想让自己的方案获得通过的关键是，事先考虑清楚“挑战者”的分配方案是什么，并用最小的代价获取最大收益，拉拢“挑战者”分配方案中最不得意的人们。<br />
真地是难以置信。P10看起来最有可能喂鲨鱼，但他牢牢地把握住先发优势，结果不但消除了死亡威胁，还获得了最大收益。而P1，看起来最安全，没有死亡的威胁，甚至还能坐收渔人之利，但却因不得不看别人脸色行事，结果连一小杯羹都无法分到，却只能够保住性命而已。</p>
<p>此类问题体现出的多方博弈情况下的生存哲学：</p>
<ol>
<li> 没有永恒的朋友，只有永恒的利益。</li>
<li> 在临界点之下，以决策者的身份出场，冒最大的风险，得到最大的利益。</li>
<li> 在接近临界点的地方，是收益分配最接近公平的地方。半数的人均匀地受益，另半数的人均匀地不受益。</li>
<li> 越过临界点之后，以决策者的身份出场，风险极大，甚至会将老本赔进去，而收益却为零，这是最糟的情况，因为大家的收益都不高。这是一种不稳定的状态，系统会通过自我调整向临界点靠拢。</li>
<li> 永远都不可能发生所有人都有收益的情况，任何时候都有至少 一半或者接近一半 人无收益，除非只有1个人。</li>
<li> 另外，如果逻辑推理没有漏洞，那么结论就必定站得住脚，即使它与你的直觉矛盾。</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.javachen.com/2010/01/pirates-share-gold/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C 的郁闷</title>
		<link>http://www.javachen.com/2010/01/c-depressed/</link>
		<comments>http://www.javachen.com/2010/01/c-depressed/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 14:35:05 +0000</pubDate>
		<dc:creator>phoenix</dc:creator>
				<category><![CDATA[C/Algorithm]]></category>
		<category><![CDATA[Post]]></category>
		<category><![CDATA[C]]></category>

		<guid isPermaLink="false">http://www.javachen.com/?p=812</guid>
		<description><![CDATA[好久没有再写C代码了，最近在网上看到一个题目，挺好的，就想做做看，可现在有陷入了以前一样的局面，还是让这样的一点都不理解的问题给困扰住了，听郁闷的。下面是源程序代码，已经在知道里面提过问的，希望大家帮忙解决。（本来是用两个文件的，最后合并了） 问题描述：一个含有偶数个元素的数组，现将其元素两两配对，求配对之后整体和谐度最高的结果数组。初始配对方案为：从第一个元素开始，两两配对。 #ifndef FORPOORCOMBINATION_ #define FORPOORCOMBINATION_ #endif /*FORPOORCOMBINATION_*/ #include &#60;stdio.h&#62; #include &#60;stdlib.h&#62; #include &#60;math.h&#62; #define MAX 100 #define LENGTH 21 int main() { int array[LENGTH]; int i = 1; int j = 0; int poortotal = 0; int temp,indextemp; int ForPoor(int array[], int index10, int index20) { int index11, index21; int old, now; if(index10 % [...]]]></description>
			<content:encoded><![CDATA[<p><span>好久没有再写C代码了，最近在网上看到一个题目，挺好的，就想做做看，可现在有陷入了以前一样的局面，还是让这样的一点都不理解的问题给困扰住了，听郁闷的。下面是源程序代码，已经在知道里面提过问的，希望大家帮忙解决。（本来是用两个文件的，最后合并了）</span></p>
<p><span>问题描述：一个含有偶数个元素的数组，现将其元素两两配对，求配对之后整体和谐度最高的结果数组。初始配对方案为：从第一个元素开始，两两配对。</span><br />
<span id="more-812"></span><br />
#ifndef FORPOORCOMBINATION_<br />
#define  FORPOORCOMBINATION_</p>
<p>#endif /*FORPOORCOMBINATION_*/</p>
<p>#include &lt;stdio.h&gt;<br />
#include &lt;stdlib.h&gt;<br />
#include  &lt;math.h&gt;</p>
<p>#define MAX 100<br />
#define LENGTH 21</p>
<p>int main()<br />
{</p>
<p>int array[LENGTH];<br />
int i = 1;<br />
int j = 0;<br />
int poortotal = 0;<br />
int temp,indextemp;</p>
<p>int ForPoor(int array[], int index10, int index20)<br />
{<br />
int  index11, index21;<br />
int old, now;<br />
if(index10 % 2 == 0)  index11 = index10 &#8211; 1;<br />
else index11 = index10 + 1;</p>
<p>if(index20 %2 == 0) index21 = index20 &#8211; 1;<br />
else index21 =  index20 + 1;</p>
<p>old = abs(array[10] &#8211; array[11]) +  abs(array[20] &#8211; array[21]);<br />
now = abs(array[20] &#8211; array[11]) +  abs(array[10] &#8211; array[21]);</p>
<p>return (now &#8211; old);<br />
}</p>
<p>/*int ForPoor(int array[], int  index10, int index20);*/</p>
<p>for(i = 1;i &lt;= 21;i  ++)<br />
{<br />
array[i] = random(MAX);<br />
printf(&#8220;\t%d&#8221;,array[i]);<br />
if((i%5) == 0)<br />
printf(&#8220;\n&#8221;);<br />
}</p>
<p>/*while(j != k)<br />
{<br />
j = random(10);<br />
k = random(10);<br />
}*/</p>
<p>for(i = 1; i &lt;= 21;)<br />
{<br />
poortotal  = poortotal + abs(array[i] &#8211; array[i + 1]);<br />
i = i + 2;<br />
}</p>
<p>for(i=LENGTH;i&gt;0;i&#8211;)<br />
{<br />
for(j = i  &#8211; 2; j &gt; 0; j &#8211;)<br />
{<br />
temp = poortotal +  ForPoor(array,i,j);</p>
<p>if(temp &lt;  poortotal)<br />
{<br />
poortotal =  temp;<br />
indextemp = j;<br />
}<br />
}<br />
temp = array[i];<br />
array[i] = array[indextemp];<br />
array[indextemp] = temp;<br />
}<br />
printf(&#8220;\n\tThe Lowest Concordance is  : %d&#8221;,poortotal);<br />
system(&#8220;PAUSE&#8221;);</p>
<p>return  1;<br />
}</p>
<p><span style="font-size: x-small;">如有解释不清楚，可以致电到</span><a href="mailto:tiantiantianlan08@163.com"><span style="font-size: x-small;">tiantiantianlan08@163.com</span></a><span style="font-size: x-small;">,也可以留言，我会尽快解释，谢谢帮助</span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.javachen.com/2010/01/c-depressed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>排序算法的实现</title>
		<link>http://www.javachen.com/2009/12/methods-of-sorting/</link>
		<comments>http://www.javachen.com/2009/12/methods-of-sorting/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 04:53:20 +0000</pubDate>
		<dc:creator>JavaChen</dc:creator>
				<category><![CDATA[C/Algorithm]]></category>
		<category><![CDATA[sort]]></category>

		<guid isPermaLink="false">http://www.javachen.com/?p=689</guid>
		<description><![CDATA[排序是一个极为常用的算法，这篇文章收集所有常见的排序算法实现，方便回顾 常见的排序算法： 1. 插入排序 O(n^2) 插入排序是最简单最直观的排序算法了，它的依据是：遍历到第N个元素的时候前面的N-1个元素已经是排序好的了，那么就查找前面的N-1个元素把这第N个元素放在合适的位置，如此下去直到遍历完序列的元素为止。 2. 堆排序(Heap Sort) n个关键字序列Kl，K2，…，Kn称为堆，当且仅当该序列满足如下性质（简称为堆性质）： （1） ki≤K2i且ki≤K2i+1 或（2）Ki≥K2i且ki≥K2i+1（1≤i≤） 若将此序列所存储的向量R[1……n]看做是一棵完全二叉树的存储结构，则堆实质上是满足如下性质的完全二叉树：树中任一非叶结点的关键字均不大于（或不小于）其左右孩子（若存在）结点的关键字。 堆的这个性质使得可以迅速定位在一个序列之中的最小（大）的元素。 堆排序算法的过程如下： （1）得到当前序列的最小（大）的元素（2）把这个元素和最后一个元素进行交换，这样当前的最小（大）的元素就放在了序列的最后，而原先的最后一个元素放到了序列的最前面（3）的交换可能会破坏堆序列的性质（注意此时的序列是除去已经放在最后面的元素），因此需要对序列进行调整，使之满足于上面堆的性质。重复上面的过程，直到序列调整完毕为止。 3. 冒泡排序(Bubble Sort) O(n^2) 每次遍历完序列都把最大（小）的元素放在最前面，然后再对剩下的序列从父前面的一个过程，每次遍历完之后待排序序列就少一个元素，当待排序序列减小为只有一个元素的时候排序就结束了。 4. 快速排序(Quick Sort)（又叫快速分划排序）O(n*logn) 选定一个枢纽元素，对待排序序列进行分割，分割之后的序列一个部分小于枢纽元素，一个部分大于枢纽元素，再对这两个分割好的子序列进行上述的过程 5. 归并排序(Merge Sort) O(n*logn) 把待排序序列分成相同大小的两个部分，依次对这两部分进行归并排序，完毕之后再按照顺序进行合并 6. 希尔排序(Shell Sort) O(n*logn)->O(n^2) shell排序是对插入排序的一个改装，它每次排序把序列的元素按照某个增量分成几个子序列，对这几个子序列进行插入排序，然后不断缩小增量扩大每个子序列的元素数量，直到增量为一的时候子序列就和原先的待排列序列一样了，此时只需要做少量的比较和移动就可以完成对序列的排序了。 7. 箱/桶排序(Box Sort / Bin Sort / Bucket Sort)]]></description>
			<content:encoded><![CDATA[<p>排序是一个极为常用的算法，这篇文章收集所有常见的排序算法实现，方便回顾</p>
<p>常见的排序算法：</p>
<p>   1.      插入排序 O(n^2)</p>
<p>      插入排序是最简单最直观的排序算法了，它的依据是：遍历到第N个元素的时候前面的N-1个元素已经是排序好的了，那么就查找前面的N-1个元素把这第N个元素放在合适的位置，如此下去直到遍历完序列的元素为止。<br />
   2.      堆排序(Heap Sort)</p>
<p>      n个关键字序列Kl，K2，…，Kn称为堆，当且仅当该序列满足如下性质（简称为堆性质）：</p>
<p>      （1） ki≤K2i且ki≤K2i+1 或（2）Ki≥K2i且ki≥K2i+1（1≤i≤）</p>
<p>      若将此序列所存储的向量R[1……n]看做是一棵完全二叉树的存储结构，则堆实质上是满足如下性质的完全二叉树：树中任一非叶结点的关键字均不大于（或不小于）其左右孩子（若存在）结点的关键字。</p>
<p>      堆的这个性质使得可以迅速定位在一个序列之中的最小（大）的元素。<br />
<span id="more-689"></span></p>
<p>      堆排序算法的过程如下：</p>
<p>      （1）得到当前序列的最小（大）的元素（2）把这个元素和最后一个元素进行交换，这样当前的最小（大）的元素就放在了序列的最后，而原先的最后一个元素放到了序列的最前面（3）的交换可能会破坏堆序列的性质（注意此时的序列是除去已经放在最后面的元素），因此需要对序列进行调整，使之满足于上面堆的性质。重复上面的过程，直到序列调整完毕为止。<br />
   3.      冒泡排序(Bubble Sort) O(n^2) 每次遍历完序列都把最大（小）的元素放在最前面，然后再对剩下的序列从父前面的一个过程，每次遍历完之后待排序序列就少一个元素，当待排序序列减小为只有一个元素的时候排序就结束了。<br />
   4.      快速排序(Quick Sort)（又叫快速分划排序）O(n*logn)</p>
<p>      选定一个枢纽元素，对待排序序列进行分割，分割之后的序列一个部分小于枢纽元素，一个部分大于枢纽元素，再对这两个分割好的子序列进行上述的过程<br />
   5.      归并排序(Merge Sort) O(n*logn)</p>
<p>      把待排序序列分成相同大小的两个部分，依次对这两部分进行归并排序，完毕之后再按照顺序进行合并<br />
   6.      希尔排序(Shell Sort) O(n*logn)->O(n^2)</p>
<p>      shell排序是对插入排序的一个改装，它每次排序把序列的元素按照某个增量分成几个子序列，对这几个子序列进行插入排序，然后不断缩小增量扩大每个子序列的元素数量，直到增量为一的时候子序列就和原先的待排列序列一样了，此时只需要做少量的比较和移动就可以完成对序列的排序了。<br />
   7.      箱/桶排序(Box Sort / Bin Sort / Bucket Sort)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javachen.com/2009/12/methods-of-sorting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
