??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲网址在线观看,亚洲国产精品毛片av不卡在线,国产l精品国产亚洲区在线观看http://m.tkk7.com/zellux/category/22032.htmlq的大二:M 思?{待zh-cnWed, 23 Apr 2008 17:14:43 GMTWed, 23 Apr 2008 17:14:43 GMT60URAL 1011http://m.tkk7.com/zellux/archive/2008/04/23/195333.htmlZelluXZelluXWed, 23 Apr 2008 14:44:00 GMThttp://m.tkk7.com/zellux/archive/2008/04/23/195333.htmlhttp://m.tkk7.com/zellux/comments/195333.htmlhttp://m.tkk7.com/zellux/archive/2008/04/23/195333.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/195333.htmlhttp://m.tkk7.com/zellux/services/trackbacks/195333.htmlProblem

Every bus in the Ekaterinburg city has a special man (or woman) called conductor. When you ride the bus, you have to give money to the conductor. We know that there are more then P% conductors and less then Q% conductors. Your task is to determine a minimal possible number of Ekaterinburg citizens.


我只能说太挫了。。。精度问题搞了半天,看来点q是要尽量化成整型再啊?br />

q有个问题就是q*i是开区间q是闭区_MWrong Answer了无数次后ȝq了。。?br />

ZelluX 2008-04-23 22:44 发表评论
]]>
URAL 题解 - wikihttp://m.tkk7.com/zellux/archive/2008/04/17/193697.htmlZelluXZelluXThu, 17 Apr 2008 03:48:00 GMThttp://m.tkk7.com/zellux/archive/2008/04/17/193697.htmlhttp://m.tkk7.com/zellux/comments/193697.htmlhttp://m.tkk7.com/zellux/archive/2008/04/17/193697.html#Feedback2http://m.tkk7.com/zellux/comments/commentRss/193697.htmlhttp://m.tkk7.com/zellux/services/trackbacks/193697.htmlhttp://www.nocow.cn/index.php

抽时间多做做Q提高下我可怜的法功底 >,<

ZelluX 2008-04-17 11:48 发表评论
]]>
《编E之》上的一道题目的讨论http://m.tkk7.com/zellux/archive/2008/04/15/192955.htmlZelluXZelluXMon, 14 Apr 2008 16:23:00 GMThttp://m.tkk7.com/zellux/archive/2008/04/15/192955.htmlhttp://m.tkk7.com/zellux/comments/192955.htmlhttp://m.tkk7.com/zellux/archive/2008/04/15/192955.html#Feedback8http://m.tkk7.com/zellux/comments/commentRss/192955.htmlhttp://m.tkk7.com/zellux/services/trackbacks/192955.html计算机科学论坛最qD办了一个阅L章,提交书评的活动,具体内容误http://www.ieee.org.cn/dispbbs.asp?boardID=42&ID=61162?/p>

q里我想针对L上的一个问题谈谈自q理解?/p>

问题很简单,求二q制?的个数。对于一个字节(8bitQ的变量Q求其二q制表示?1"的个敎ͼ要求法的执行效率尽可能的高?/p>

先来看看L上给出的几个法Q?/p>

解法一Q每ơ除二,看是否ؓ奇数Q是的话q计加一Q最后这个结果就是二q制表示?的个数?/p>

解法二,同样用到一个@环,只是里面的操作用位移操作化了?/p>

   1:  int Count(int v)  
   2:  {  
   3:      int num = 0;
   4:      while (v) {  
   5:          num += v & 0x01;  
   6:          v >>= 1;  
   7:      }  
   8:      return num;  
   9:  }

解法三,用到一个y妙的与操作,v & (v -1 )每次能消Mq制表示中最后一?Q利用这个技巧可以减一定的循环ơ数?/p>

解法四,查表法,因ؓ只有数据8bitQ直接徏一张表Q包含各个数?的个敎ͼ然后查表p。复杂度O(1)?/p>

   1:  int countTable[256] = { 0, 1, 1, 2, 1, ..., 7, 7, 8 };  
   2:     
   3:  int Count(int v) {  
   4:      return countTable[v];  
   5:  }
  
好了Q这是L上给出的四种ҎQ下面谈谈我的看法?/p>

首先是对法的衡量上Q复杂度真的是唯一的标准吗Q尤其对于这U数据规模给定,而且很小的情况下Q复杂度其实是个比较ơ要的因素?/p>

查表法的复杂度ؓO(1)Q我用解法一Q@环八ơ固定,复杂度也是O(1)。至于数据规模变大,变成32位整型,那查表法自然也不合适了?/p>

其次Q我觉得既然是这样一个很的操作Q衡量的度也必然要,CPU旉周期可以作ؓ一个参考?/p>

解法一里有若干ơ整数加法,若干ơ整数除法(一般的~译器都能把它优化成位移Q,q有几个循环分支判断Q几个奇偶性判断(q个比较耗时_ҎCSAPP上的数据Q一般一个branch penalty得耗掉14个左右的cycleQ,加v来大概几十个cycle吧?/p>

再看解法四,查表法看gơ地址计算p解决Q但实际上这里用C个访存操作,而且W一ơ访存的时候很有可能那个数l不在cache里,q样一个cache missD的后果可能就是耗去几十甚至上百个cycleQ因讉K内存Q。所以对于这U“小操作”,q个法的性能其实是很差的?/p>

q里我再推荐几个解决q个问题的算法,?2位无W号整型Z?/p>

   1:  int Count(unsigned x) {  
   2:     x = x - ((x >> 1) & 0x55555555);   
   3:     x = (x & 0x33333333) + ((x >> 2) & 0x33333333);   
   4:     x = (x + (x >> 4)) & 0x0F0F0F0F;   
   5:     x = x + (x >> 8);   
   6:     x = x + (x >> 16);   
   7:     return x & 0x0000003F;   
   8:  }
  
q里用的是二分法Q两两一l相加,之后四个四个一l相加,接着八个八个Q最后就得到各位之和了?/p>

q有一个更巧妙的HAKMEM法

   1:  int Count(unsigned x) {
   2:     unsigned n;   
   3:     
   4:     n = (x >> 1) & 033333333333;   
   5:     x = x - n;  
   6:     n = (n >> 1) & 033333333333;  
   7:     x = x - n;   
   8:     x = (x + (x >> 3)) & 030707070707;  
   9:     x = modu(x, 63); 
   10:     return x;  
   11:  }
  
首先是将二进制各位三个一l,求出每组?的个敎ͼ然后盔R两组归ƈQ得到六个一l的1的个敎ͼ最后很巧妙的用?3取余得到了结果?/p>

因ؓ2^6 = 64Q也是?x_0 + x_1 * 64 + x_2 * 64 * 64 = x_0 + x_1 + x_2 (mod 63)Q这里的{号表示同余?/p>

q个E序只需要十条左x令,而且不访存,速度很快?/p>

由此可见Q衡量一个算法实际效果不单要看复杂度Q还要结合其他情况具体分析?/p>

关于后面的两道扩展问题,问题一是问32位整型如何处理,q个上面已经讲了?/p>

问题二是l定两个整数A和BQ问A和B有多位是不同的?/p>

q个问题其实是?问题多了一个步骤,只要先算出A和B的异或结果,然后求这个g1的个数就行了?br />
M看来q本书还是很不错的,比较喜欢里面针对一个问题提Z同算法ƈ不断改进的风根{这里提Z点个人的理解Q望大家指正 ;-)

(by ZelluX   http://m.tkk7.com/zellux)



ZelluX 2008-04-15 00:23 发表评论
]]>
求n?2位无W号整数中异或后值最大的两个?/title><link>http://m.tkk7.com/zellux/archive/2008/04/10/191717.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Wed, 09 Apr 2008 16:33:00 GMT</pubDate><guid>http://m.tkk7.com/zellux/archive/2008/04/10/191717.html</guid><wfw:comment>http://m.tkk7.com/zellux/comments/191717.html</wfw:comment><comments>http://m.tkk7.com/zellux/archive/2008/04/10/191717.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://m.tkk7.com/zellux/comments/commentRss/191717.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/zellux/services/trackbacks/191717.html</trackback:ping><description><![CDATA[     摘要: 问题Q?<br>l定n?2位无W号整数Q求出其中异或结果最大的两个整数?nbsp; <a href='http://m.tkk7.com/zellux/archive/2008/04/10/191717.html'>阅读全文</a><img src ="http://m.tkk7.com/zellux/aggbug/191717.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/zellux/" target="_blank">ZelluX</a> 2008-04-10 00:33 <a href="http://m.tkk7.com/zellux/archive/2008/04/10/191717.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SICP 习题记录 (1)http://m.tkk7.com/zellux/archive/2008/04/03/188018.htmlZelluXZelluXThu, 03 Apr 2008 14:33:00 GMThttp://m.tkk7.com/zellux/archive/2008/04/03/188018.htmlhttp://m.tkk7.com/zellux/comments/188018.htmlhttp://m.tkk7.com/zellux/archive/2008/04/03/188018.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/188018.htmlhttp://m.tkk7.com/zellux/services/trackbacks/188018.html
Ex 2.18
把一个列表倒过来。不习惯在lisp里用iterative方式 >,<

接下来几题都是Map-Reduce思想的应用(或者照书上的说法,用enumerator - filter - map - accumulatorq四个步骤操作一个listQ?br />
用到的几个函敎ͼ

enumrate-tree 的功能是遍历一个树状结构,把其中的所有叶子保存在一个list中?br />
Ex 2.34
利用Horner's rule计算多项式结果(q公式这几天q经常碰刎ͼ

Ex 2.35
数出一|中的叶子数。这题我的做法比较土Q没惛_map-reduce操作上的递归Q而是把叶子节点的值都Ҏ1然后一个篏加?/p>

其实只要递归调用d数就行了

Ex 2.36
可以理解矩阵各列之和吧


> (accumulate-n + 0 (list (list 1 2 3) (list 4 5 6) (list 7 8 9) (list 10 11 12)))
(22 26 30)

ZelluX 2008-04-03 22:33 发表评论
]]>
正则表达式的复杂?/title><link>http://m.tkk7.com/zellux/archive/2008/03/27/188904.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Wed, 26 Mar 2008 16:21:00 GMT</pubDate><guid>http://m.tkk7.com/zellux/archive/2008/03/27/188904.html</guid><wfw:comment>http://m.tkk7.com/zellux/comments/188904.html</wfw:comment><comments>http://m.tkk7.com/zellux/archive/2008/03/27/188904.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/zellux/comments/commentRss/188904.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/zellux/services/trackbacks/188904.html</trackback:ping><description><![CDATA[ <p>其实理解了 Regular Expression -> NFA -> DFA q个q程Q大致的复杂度确定也不难<br /><br />发信? styc (styc), 信区: Algorithm<br />标?? Re: 请问一下大家正则表辑ּ的时间复杂度<br />发信? 水木C֌ (Wed Mar 26 20:37:02 2008), 站内</p> <p>NFA构造O(n)Q匹配O(nm)<br />DFA构造O(2^n)Q最化O(kn'logn')QN'=O(2^n)Q,匚wO(m)<br />n=regex长度Qm=串长Qk=字母表大,n'=原始的dfa大小<br />大概是这样子?br /></p> <img src ="http://m.tkk7.com/zellux/aggbug/188904.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/zellux/" target="_blank">ZelluX</a> 2008-03-27 00:21 <a href="http://m.tkk7.com/zellux/archive/2008/03/27/188904.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Minesweeper is NP-completehttp://m.tkk7.com/zellux/archive/2008/02/06/179406.htmlZelluXZelluXWed, 06 Feb 2008 11:40:00 GMThttp://m.tkk7.com/zellux/archive/2008/02/06/179406.htmlhttp://m.tkk7.com/zellux/comments/179406.htmlhttp://m.tkk7.com/zellux/archive/2008/02/06/179406.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/179406.htmlhttp://m.tkk7.com/zellux/services/trackbacks/179406.html
居然是NPC...

ZelluX 2008-02-06 19:40 发表评论
]]>
Tom Duff on Duff's Devicehttp://m.tkk7.com/zellux/archive/2007/11/29/164015.htmlZelluXZelluXThu, 29 Nov 2007 08:02:00 GMThttp://m.tkk7.com/zellux/archive/2007/11/29/164015.htmlhttp://m.tkk7.com/zellux/comments/164015.htmlhttp://m.tkk7.com/zellux/archive/2007/11/29/164015.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/164015.htmlhttp://m.tkk7.com/zellux/services/trackbacks/164015.html Summary: Original citation
From: td@alice.UUCP (Tom Duff)
Organization: AT&T Bell Laboratories, Murray Hill NJ
Date: 29 Aug 88 20:33:51 GMT
Message-ID: <8144@alice.UUCP>

I normally do not read comp.lang.c, but Jim McKie told me that ``'' had come up in comp.lang.c again.  I have lost the version that was sent to netnews in May 1984, but I have reproduced below the note in which I originally proposed the device.  (If anybody has a copy of the netnews version, I would gratefully receive a copy at research!td or td@research.att.com.)

To clear up a few points:

  1. The point of the device is to express general loop unrolling directly in C.  People who have posted saying `just use memcpy' have missed the point, as have those who have criticized it using various machine-dependent memcpy implementations as support.  In fact, the example in the message is not implementable as memcpy, nor is any computer likely to have an memcpy-like idiom that implements it.

     

  2. Somebody claimed that while the device was named for me, I probably didn't invent it.  I almost certainly did invent it.  I had definitely not seen or heard of it when I came upon it, and nobody has ever even claimed prior knowledge, let alone provided dates and times.  Note the headers on the message below:  apparently I invented the device on November 9, 1983, and was proud (or disgusted) enough to send mail to dmr Please note that I do not claim to have invented loop unrolling, merely this particular expression of it in C.

     

  3. The device is legal dpANS C.  I cannot quote chapter and verse, but Larry Rosler, who was chairman of the language subcommittee (I think), has assured me that X3J11 considered it carefully and decided that it was legal. Somewhere I have a note from dmr certifying that all the compilers that he believes in accept it.  Of course, the device is also legal C++, since Bjarne uses it in his book.

     

  4. Somebody invoked (or more properly, banished) the `false god of efficiency.'  Careful reading of my original note will put this slur to rest.  The alternative to genuflecting before the god of code-bumming is finding a better algorithm.  It should be clear that none such was available.  If your code is too slow, you must make it faster.  If no better algorithm is available, you must trim cycles.

     

  5. The same person claimed that the device wouldn't exhibit the desired speed-up.  The argument was flawed in two regards:  first, it didn't address the performance of the device, but rather the performance of one of its few uses (implementing memcpy) for which many machines have a high-performance idiom.  Second, the poster made his claims in the absence of timing data, which renders his assertion suspect.  A second poster tried the test, but botched the implementation, proving only that with diligence it is possible to make anything run slowly.

     

  6. Even Henry Spencer, who hit every other nail square on the end with the flat round thing stuck to it, made a mistake (albeit a trivial one).  Here is Henry replying to bill@proxftl.UUCP (T. William Wells):
       >>... Dollars to doughnuts this
        >>was written on a RISC machine.
        >Nope.  Bell Labs Research uses VAXen and 68Ks, mostly.
        

    I was at Lucasfilm when I invented the device.

     

  7. Transformations like this can only be justified by measuring the resulting code.  Be careful when you use this thing that you don't unwind the loop so much that you overflow your machine's instruction cache.  Don't try to be smarter than an over-clever C compiler that recognizes loops that implement block move or block clear and compiles them into machine idioms.

Here then, is the original document describing Duff's device:

From research!ucbvax!dagobah!td  Sun Nov 13 07:35:46 1983
Received: by ucbvax.ARPA (4.16/4.13)  id AA18997; Sun, 13 Nov 83 07:35:46 pst
Received: by dagobah.LFL (4.6/4.6b)  id AA01034; Thu, 10 Nov 83 17:57:56 PST
Date: Thu, 10 Nov 83 17:57:56 PST
From: ucbvax!dagobah!td (Tom Duff)
Message-Id: <8311110157.AA01034@dagobah.LFL>
To: ucbvax!decvax!hcr!rrg, ucbvax!ihnp4!hcr!rrg, ucbvax!research!dmr, ucbvax!research!rob

Consider the following routine, abstracted from code which copies an array of shorts into the Programmed IO data register of an Evans & Sutherland Picture System II:

 
send(to, from, count)
register 
short *to, *from;
register count;
{
    
do
        
*to = *from++;
    
while (--count>0);
}

(Obviously, this fails if the count is zero.)
The VAX C compiler compiles the loop into 2 instructions (a movw and a sobleq,
I think.)  As it turns out, this loop was the bottleneck in a real-time animation playback program which ran too slowly by about 50%.  The standard way to get more speed out of something like this is to unwind the loop a few times, decreasing the number of sobleqs.  When you do that, you wind up with a leftover partial loop.  I usually handle this in C with a switch that indexes a list of copies of the original loop body.  Of course, if I were writing assembly language code, I'd just jump into the middle of the unwound loop to deal with the leftovers.  Thinking about this yesterday, the following implementation occurred to me:

 

send(to, from, count)
    register 
short *to, *from;
    register count;
{
    register n
=(count+7)/8;
    
switch(count%8{
        
case 0:    do {    *to = *from++;
        
case 7:        *to = *from++;
        
case 6:        *to = *from++;
        
case 5:        *to = *from++;
        
case 4:        *to = *from++;
        
case 3:        *to = *from++;
        
case 2:        *to = *from++;
        
case 1:        *to = *from++;
        }
 while(--n>0);
    }

}

Disgusting, no?  But it compiles and runs just fine.  I feel a combination of pride and revulsion at this discovery.  If no one's thought of it before, I think I'll name it after myself.

It amazes me that after 10 years of writing C there are still little corners that I haven't explored fully.  (Actually, I have another revolting way to use switches to implement interrupt driven state machines but it's too horrid to go into.)

Many people (even bwk?) have said that the worst feature of C is that switches don't break automatically before each case label.  This code forms some sort of argument in that debate, but I'm not sure whether it's for or against.

yrs trly
Tom



ZelluX 2007-11-29 16:02 发表评论
]]>
In-place Matrix Transpositionhttp://m.tkk7.com/zellux/archive/2007/11/12/159996.htmlZelluXZelluXMon, 12 Nov 2007 08:16:00 GMThttp://m.tkk7.com/zellux/archive/2007/11/12/159996.htmlhttp://m.tkk7.com/zellux/comments/159996.htmlhttp://m.tkk7.com/zellux/archive/2007/11/12/159996.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/159996.htmlhttp://m.tkk7.com/zellux/services/trackbacks/159996.html from wikipedia

http://m.tkk7.com/Files/zellux/In-place_matrix_transposition.zip


ZelluX 2007-11-12 16:16 发表评论
]]>
后缀树的在线生成法http://m.tkk7.com/zellux/archive/2007/11/07/158935.htmlZelluXZelluXWed, 07 Nov 2007 13:08:00 GMThttp://m.tkk7.com/zellux/archive/2007/11/07/158935.htmlhttp://m.tkk7.com/zellux/comments/158935.htmlhttp://m.tkk7.com/zellux/archive/2007/11/07/158935.html#Feedback1http://m.tkk7.com/zellux/comments/commentRss/158935.htmlhttp://m.tkk7.com/zellux/services/trackbacks/158935.html 不过当时只是有了个印象?br /> 现在发现q东东还是很好用?nbsp; @,@

http://m.tkk7.com/Files/zellux/SuffixT1withFigs.rar

On–line construction of suffix trees
by Esko Ukkonen

Key Words.
Linear time algorithm, suffix tree, suffix trie, suffix automaton, DAWG.

Abstract.
An on–line algorithm is presented for constructing the suffix tree for a given string in time linear in the length of the string. The new algorithm has the desirable property of processing the string symbol by symbol from left to right. It has always the suffix tree for the scanned part of the string ready. The method is developed as a linear–time version of a very simple algorithm for (quadratic size) suffix tries. Regardless of its quadratic worst-case this latter algorithm can be a good practical method when the string is not too long. Another variation of this method is shown to give in a natural way the well–known algorithms for constructing suffix automata (DAWGs).



ZelluX 2007-11-07 21:08 发表评论
]]>
U烦二叉?/title><link>http://m.tkk7.com/zellux/archive/2007/11/07/158758.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Wed, 07 Nov 2007 03:02:00 GMT</pubDate><guid>http://m.tkk7.com/zellux/archive/2007/11/07/158758.html</guid><wfw:comment>http://m.tkk7.com/zellux/comments/158758.html</wfw:comment><comments>http://m.tkk7.com/zellux/archive/2007/11/07/158758.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/zellux/comments/commentRss/158758.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/zellux/services/trackbacks/158758.html</trackback:ping><description><![CDATA[发现居然q是Pascal描述Q亲切啊亲切<br /> <br /> http://iprai.hust.edu.cn/icl2002/algorithm/datastructure/basic/binary_tree/chapter5_4.htm<br /> <br /> <h2>U烦二叉?/h2> <p>?a >用二叉链表作Z叉树的存储结?/a>Ӟ因ؓ每个l点中只有指向其左、右儿子l点的指针,所以从Ml点出发只能直接扑ֈ该结点的左、右儿子。在一般情况下靠它无法直接扑ֈ该结点在某种遍历序下的前驱和后l点。如果在每个l点中增加指向其前驱和后l结点的指针Q将降低存储I间的效率?/p> <p>我们可以证明Q在n个结点的二叉链表中含有n+1个空指针。因为含n个结点的二叉链表中含有个指针Q除了根l点Q每个结炚w有一个从父结Ҏ向该l点的指针,因此一׃用了n-1个指针,所以在n个结点的二叉链表中含有n+1个空指针?/p> <p>因此可以利用q些I指针,存放指向l点在某U遍历次序下的前驱和后l点的指针。这U附加的指针UCؓ<font face="楷体_GB2312">U烦</font>Q加上了U烦的二叉链表称?font face="楷体_GB2312">U烦链表</font>Q相应的二叉树称?font face="楷体_GB2312">U烦二叉?/font>。ؓ了区分一个结点的指针是指向其儿子的指针,q是指向其前驱或后l点的线索,可在每个l点中增加两个线索标志。这PU烦二叉树结点类型定义ؓQ?/p> <div align="center"> <center> <table cellpadding="5" width="90%" bgcolor="#e0e0e0" border="0"> <tbody> <tr> <td width="100%"> <p style="margin-top: 5px; margin-bottom: 5px">type</p> <p style="margin-top: 5px; margin-bottom: 5px"> TPosition=^thrNodeType;</p> <p style="margin-top: 5px; margin-bottom: 5px"> thrNodeType=record</p> <p style="margin-top: 5px; margin-bottom: 5px">              Label:LabelType;</p> <p style="margin-top: 5px; margin-bottom: 5px">              ltag,rtag:0..1;</p> <p style="margin-top: 5px; margin-bottom: 5px">              LeftChild,RightChild:TPosition;</p> <p style="margin-top: 5px; margin-bottom: 5px">             end; </p> </td> </tr> </tbody> </table> </center></div> <p>其中ltag为左U烦标志Qrtag为右U烦标志。它们的含义?</p> <ul> <li>ltag=0QLeftChild是指向结点左儿子的指针; <li>ltag=1QLeftChild是指向结点前q左线索?br /> <li>rtag=0QRightChild是指向结点右儿子的指针; <li>rtag=1QRihgtChild是指向结点后l的右线索?</li> </ul> <p>例如?3(a)是一中序线索二叉树Q它的线索链表如?3(b)所C?/p> <blockquote> <p align="center"><img height="218" src="http://iprai.hust.edu.cn/icl2002/algorithm/datastructure/basic/binary_tree/images/img3.gif" width="263" border="0" alt="" /></p> <p align="center">(a)</p> <p align="center"><img height="372" src="http://iprai.hust.edu.cn/icl2002/algorithm/datastructure/basic/binary_tree/images/img4.gif" width="523" border="0" alt="" /></p> <p align="center">(b)</p> <p align="center">?3 U烦二叉树及其线索链?/p> </blockquote> <p>?3(b)中,在二叉树的线索链表上增加了一个头l点Q其LeftChild指针指向二叉树的根结点,其RightChild指针指向中序遍历时的最后一个结炏V另外,二叉树中依中序列表的W一个结点的LeftChild指针Q和最后一个结点的RightChild指针都指向头l点。这像Z叉树建立了一个双向线索链表,既可从第一个结点vQ顺着后q行遍历Q也可从最后一个结点v着前驱q行遍历?/p> <p>如何在线索二叉树中找l点的前驱和后l点Q以?3的中序线索二叉树Z。树中所有叶l点的右链是U烦Q因此叶l点的RightChild指向该结点的后l点Q如?3中结?b"的后lؓl点"*"。当一个内部结点右U烦标志?Ӟ其RightChild指针指向其右儿子Q因此无法由RightChild得到其后l结炏V然而,׃序遍历的定义可知Q该l点的后l应是遍历其叛_树时讉K的第一个结点,卛_子树中最左下的结炏V例如在扄?*"的后l时Q首先沿x针找到其叛_树的根结?-"Q然后沿其LeftChild指针往下直臛_左线索标志ؓ1的结点,即ؓ其后l结?在图中是l点"c")。类似地Q在中序U烦树中扄点的前驱l点的规律是Q若该结点的左线索标志ؓ1Q则LeftChild为线索,直接指向其前q点,否则遍历左子树时最后访问的那个l点Q即左子树中最右下的结点ؓ其前q炏V由此可知,若线索二叉树的高度ؓhQ则在最坏情况下Q可?em>O</em>(h)旉内找C个结点的前驱或后l结炏V在对中序线索二叉树q行遍历Ӟ无须像非U烦树的遍历那样Q利用递归引入栈来保存待访问的子树信息?/p> <p>对一非U烦二叉树以某种ơ序遍历使其变ؓ一늺索二叉树的过E称?font face="楷体_GB2312">二叉树的U烦?/font>。由于线索化的实质是二叉链表中的空指针改ؓ指向l点前驱或后l的U烦Q而一个结点的前驱或后l结点的信息只有在遍历时才能得到Q因此线索化的过E即为在遍历q程中修改空指针的过E。ؓ了记下遍历过E中讉Kl点的先后次序,可附设一个指针pre始终指向刚刚讉Kq的l点。当指针p指向当前讉K的结ҎQpre指向它的前驱。由此也可推知pre所指结点的后为p所指的当前l点。这样就可在遍历q程中将二叉树线索化。对于找前驱和后l结点这二种q算而言Q线索树优于非线索树。但U烦树也有其~点。在q行插h和删除操作时Q线索树比非U烦树的旉开销大。原因在于在U烦树中q行插h和删除时Q除了修改相应的指针外,q要修改相应的线索?/p> <!-- #EndEditable --><script src="../../../lib/footer.js"> </script> <img src ="http://m.tkk7.com/zellux/aggbug/158758.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/zellux/" target="_blank">ZelluX</a> 2007-11-07 11:02 <a href="http://m.tkk7.com/zellux/archive/2007/11/07/158758.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>取石子游?/title><link>http://m.tkk7.com/zellux/archive/2007/10/31/157272.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Wed, 31 Oct 2007 10:11:00 GMT</pubDate><guid>http://m.tkk7.com/zellux/archive/2007/10/31/157272.html</guid><wfw:comment>http://m.tkk7.com/zellux/comments/157272.html</wfw:comment><comments>http://m.tkk7.com/zellux/archive/2007/10/31/157272.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://m.tkk7.com/zellux/comments/commentRss/157272.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/zellux/services/trackbacks/157272.html</trackback:ping><description><![CDATA[     摘要: 问题Q?<br>有两堆石子,数量LQ可以不同。游戏开始由两个取矛_。游戏规定,每次有两U不同的取法Q一是可以在L的一堆中取走L多的矛_Q二是可以在两堆中同时取走相同数量的矛_。最后把矛_全部取完者ؓ胜者。现在给出初始的两堆矛_的数目,如果轮到你先取,假设双方都采取最好的{略Q问最后你是胜者还是|者?nbsp; <a href='http://m.tkk7.com/zellux/archive/2007/10/31/157272.html'>阅读全文</a><img src ="http://m.tkk7.com/zellux/aggbug/157272.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/zellux/" target="_blank">ZelluX</a> 2007-10-31 18:11 <a href="http://m.tkk7.com/zellux/archive/2007/10/31/157272.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>支持O(1)旉push pop minҎ的栈http://m.tkk7.com/zellux/archive/2007/10/29/156777.htmlZelluXZelluXMon, 29 Oct 2007 13:30:00 GMThttp://m.tkk7.com/zellux/archive/2007/10/29/156777.htmlhttp://m.tkk7.com/zellux/comments/156777.htmlhttp://m.tkk7.com/zellux/archive/2007/10/29/156777.html#Feedback2http://m.tkk7.com/zellux/comments/commentRss/156777.htmlhttp://m.tkk7.com/zellux/services/trackbacks/156777.html法评习题
题目很简单,但是代码很漂?br />
[zz]

template <typename T>
class min_stack {
public:
  
void push(const T& v) {
    s.push(make_pair(v, empty()
||v<s.top().second ? v : s.top().second));
  }


  
void pop() { s.pop(); }

  
const T& top() return s.top().first; }

  
const T& min() return s.top().second; }

  
bool empty() return s.empty(); }

private:
  std::stack
<std::pair<T, T> > s;
}
;


ZelluX 2007-10-29 21:30 发表评论
]]>
一道网易的W试?/title><link>http://m.tkk7.com/zellux/archive/2007/10/21/154762.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Sun, 21 Oct 2007 14:05:00 GMT</pubDate><guid>http://m.tkk7.com/zellux/archive/2007/10/21/154762.html</guid><wfw:comment>http://m.tkk7.com/zellux/comments/154762.html</wfw:comment><comments>http://m.tkk7.com/zellux/archive/2007/10/21/154762.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/zellux/comments/commentRss/154762.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/zellux/services/trackbacks/154762.html</trackback:ping><description><![CDATA[     摘要: 水木上看到的 <br> <br>一个K位的数N (K<=2000,N<=10^20) <br>扑և一个比N大且最接近的数Q这个数的每位之和与N相同 <br>用代码实C <br> <br>如: <br>0050 所求数?104 <br>112 所求数?21 <br>  <a href='http://m.tkk7.com/zellux/archive/2007/10/21/154762.html'>阅读全文</a><img src ="http://m.tkk7.com/zellux/aggbug/154762.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/zellux/" target="_blank">ZelluX</a> 2007-10-21 22:05 <a href="http://m.tkk7.com/zellux/archive/2007/10/21/154762.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>摩根的算法题http://m.tkk7.com/zellux/archive/2007/10/21/154777.htmlZelluXZelluXSun, 21 Oct 2007 14:05:00 GMThttp://m.tkk7.com/zellux/archive/2007/10/21/154777.htmlhttp://m.tkk7.com/zellux/comments/154777.htmlhttp://m.tkk7.com/zellux/archive/2007/10/21/154777.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/154777.htmlhttp://m.tkk7.com/zellux/services/trackbacks/154777.html阅读全文

ZelluX 2007-10-21 22:05 发表评论
]]>
PKU1065 - Wooden Stickshttp://m.tkk7.com/zellux/archive/2007/10/17/153717.htmlZelluXZelluXWed, 17 Oct 2007 15:58:00 GMThttp://m.tkk7.com/zellux/archive/2007/10/17/153717.htmlhttp://m.tkk7.com/zellux/comments/153717.htmlhttp://m.tkk7.com/zellux/archive/2007/10/17/153717.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/153717.htmlhttp://m.tkk7.com/zellux/services/trackbacks/153717.html  不管q题多简单,咔咔

按照木块的长度或质量排序Q之后贪心即可,后面和NOIP的拦截导弹一栗?

ZelluX 2007-10-17 23:58 发表评论
]]>
PKU1042 ?Gone Fishinghttp://m.tkk7.com/zellux/archive/2007/10/17/153630.htmlZelluXZelluXWed, 17 Oct 2007 09:25:00 GMThttp://m.tkk7.com/zellux/archive/2007/10/17/153630.htmlhttp://m.tkk7.com/zellux/comments/153630.htmlhttp://m.tkk7.com/zellux/archive/2007/10/17/153630.html#Feedback2http://m.tkk7.com/zellux/comments/commentRss/153630.htmlhttp://m.tkk7.com/zellux/services/trackbacks/153630.html我的做法是枚举最q到辄湖,减去相应的时间后贪心?br />
贪心旉要徏立一个堆Q用了STL中的priority_queueQ然后就不知道如何设|less<>Ҏ了。。?br /> 最后是通过自定义一个类node解决?br />
一开始写的operator<Ҏ逻辑上有问题QVS 2005跑了一会儿冒Z Debug assert errorQ这个挺赞的

D我WA的几个数据:
1) 收益?的几l数据。由于一开始设|的maxgؓ0Q因此当正解也是0时ƈ没有记录下当前的最优解。max初始值即可?br /> 2) 同样?D的问题?收益的钓鱼点也可能出现在堆中Q此时应该放弃这个点Q把旉保留l序数大的钓鱼点?

另外我有q次比赛的测试数据和标程Q需要的朋友留言卛_?/p>


 

#include <iostream>
#include 
<fstream>
#include 
<vector>
#include 
<queue>

using namespace std;

class node {
public
    
int first, second;

    node(
int x, int y)
    
{
        first 
= x;
        second 
= y;
    }


    
bool operator< (const node &rhs) const
    
{
        
if (second < rhs.second) 
            
return true;
        
else if (second > rhs.second)
            
return false;
        
else return (first > rhs.first);
    }

}
;


int main()
{
    
int n, h;
    
int d[26], t[26], f[26];
    priority_queue
<node, vector<node>, less<vector<node>::value_type> > heap;
    vector
<int> best(26);
    cin 
>> n;
    
while (true{
        
if (n == 0break;
        cin 
>> h;
        
for (int i = 1; i <= n; i++)
            cin 
>> f[i];

        
for (int i = 1; i <= n; i++)
            cin 
>> d[i];

        t[
0= 0;
        
for (int i = 1; i < n; i++)
            cin 
>> t[i];

        best.clear();
        
int max = -1;
        
// i indicates the last lake
        for (int i = 1; i <= n; i++{
            vector
<int> tempBest(26);
            
int valueGet = 0;
            
            
int timeLeft = h * 12;
            
for (int j = 1; j <= i; j++)
                timeLeft 
-=    t[j - 1];

            
if (timeLeft <= 0break;
            
while (!heap.empty())
                heap.pop();

            
for (int j = 1; j <= i; j++)
                heap.push(node(j, f[j]));

            
while ((!heap.empty()) && (timeLeft > 0)) {
                
int next = heap.top().first;
                
if (heap.top().second > 0{
                    timeLeft
--;
                    tempBest[next]
++;
                    valueGet 
+= heap.top().second;
                }

                
int valueLeft = heap.top().second - d[next];
                heap.pop();
                
if (valueLeft > 0)
                    heap.push(node(next, valueLeft));
            }

            
if (valueGet > max) {
                max 
= valueGet;
                best 
= tempBest;
                
if (timeLeft > 0)
                    best[
1+= timeLeft;
            }

        }

        printf(
"%d", best[1* 5);
        
for (int i = 2; i <= n; i++)
            printf(
", %d", best[i] * 5);
        printf(
"\nNumber of fish expected: %d\n", max);
        cin 
>> n;
        
if (n != 0) cout << endl;
    }

    
return 0;
}



ZelluX 2007-10-17 17:25 发表评论
]]>
CLRS 习题 16.1-3 Interval-graph Coloring Problemhttp://m.tkk7.com/zellux/archive/2007/10/14/152667.htmlZelluXZelluXSat, 13 Oct 2007 16:48:00 GMThttp://m.tkk7.com/zellux/archive/2007/10/14/152667.htmlhttp://m.tkk7.com/zellux/comments/152667.htmlhttp://m.tkk7.com/zellux/archive/2007/10/14/152667.html#Feedback2http://m.tkk7.com/zellux/comments/commentRss/152667.htmlhttp://m.tkk7.com/zellux/services/trackbacks/152667.html 已知一些活动的h旉{Si}, {Fi}Q把它们安排在若q个大厅中进行,要求M大厅L旉D内不能有两Ҏ动同时进行,求出所需的最的大厅数?br />
分析Q?from CLRS Instructor's Manual)

q是一个区间图的着色问?Interval-graph Coloring Problem)Q用点表C活动,把时间冲H的zdqv来,然后q行点的着Ԍ要求同一U段的两端不能有相同颜色的点?br />
首先最Ҏ惛_的就是用书上的Greedy-Activity-Selector扑և可安排在大厅1的最长序列,然后删去q些zdQ再ơ调用该ҎQ找出安排在大厅2的活动,以此cL?br /> 复杂度O(n*n)

q有一个O(n*logn)的算法,甚至在v止时间都是比较小的数字时复杂度只有O(n)?br />
主要思想是依ơ遍历每个活动,把它们安排到不同的大厅中?br /> l护两张表,一张记录当前时间t已经安排了活动的大厅Q另一张记录当前时间空闲的大厅
然后从头扫描排序后的旉点序列(如果事ga的结束时间等于时间b的开始时_那么前者应该排在后者后面)
到开始时间tQ把该活动放到空闲列表的W一个大厅中Q如果空闲列表ؓI则新加一个大厅)Q然后把该大厅放入已安排的大厅列表中Q?br /> 到l束旉tQ从已安排的大厅列表中移出相应大厅到I闲列表?br />
复杂度分析:
排序QO(n logn)Q如果时间范围有限制q可以做到O(n)
处理QO(n)

ZelluX 2007-10-14 00:48 发表评论
]]>
求相L最大间?/title><link>http://m.tkk7.com/zellux/archive/2007/10/07/150850.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Sun, 07 Oct 2007 08:06:00 GMT</pubDate><guid>http://m.tkk7.com/zellux/archive/2007/10/07/150850.html</guid><wfw:comment>http://m.tkk7.com/zellux/comments/150850.html</wfw:comment><comments>http://m.tkk7.com/zellux/archive/2007/10/07/150850.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/zellux/comments/commentRss/150850.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/zellux/services/trackbacks/150850.html</trackback:ping><description><![CDATA[Problem: You are given n real numbers - they are NOT sorted. Develop a linear timeQO(n)Qalgorithm to find the largest gap between consecutive numbers when the n numbers are sorted. For example, given:<br /> 10 23 7 1 35 27 50 41<br /> the algorithm should produce 13 as its result, since the sorted list is:<br /> 1 7 10 23 27 35 41 50<br /> and the largest gap is 13 (between 10 and 23).<br /> <br /> Please note that your algorithm cannot actually sort the n numbers.<br /> <br />    Macsy (真心) ? (Fri Oct  5 11:59:16 2007)  提到:<br /> <br /> 有一个方法需要额外的O(n)的空间?br /> 首先扑ֈ最大最数max,min<br /> max gap 肯定不小?(max-min)/n ?br /> 然后?max-min)/n为步长,建立n个桶<br /> 每个桉面记录落在这个桶中的最大最倹{?br /> 最后顺序扫描这n个桶中的值就可以了?br /> <br /> 大概代码?br /> input: a[n];<br /> <br /> min=min_of(a[1..n]);<br /> max=max_of(a[1..n]);<br /> step=(max-min)/n;<br /> <br /> b[0..n].min=maxfloat; b[0..n].max=-maxfloat;<br /> for i=1 to n<br />   ind = (a[i]-min)/step;<br />   b[ind].min=min(b[ind].min, a[i]);<br />   b[ind].max=max(b[ind].max, a[i]);<br /> <br /> maxgap=step;<br /> last=b[0].max;<br /> for i=1 to n<br />   if (b[i].min != maxfloat)<br />     maxgap=max(maxgap, b[i].min-last);<br />     last=b[i].max;<br /> <br /> output maxgap<br /> <br /> <img src ="http://m.tkk7.com/zellux/aggbug/150850.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/zellux/" target="_blank">ZelluX</a> 2007-10-07 16:06 <a href="http://m.tkk7.com/zellux/archive/2007/10/07/150850.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个百度面试题 - n个数中找最大的两个数最比较次?/title><link>http://m.tkk7.com/zellux/archive/2007/10/01/150031.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Mon, 01 Oct 2007 03:07:00 GMT</pubDate><guid>http://m.tkk7.com/zellux/archive/2007/10/01/150031.html</guid><wfw:comment>http://m.tkk7.com/zellux/comments/150031.html</wfw:comment><comments>http://m.tkk7.com/zellux/archive/2007/10/01/150031.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/zellux/comments/commentRss/150031.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/zellux/services/trackbacks/150031.html</trackback:ping><description><![CDATA[from 水木<br /> <br /> 1. 两两比较Q找出最大的Qn-1?br /> 2. 从找最大的q条路线回溯Q次大的必然在这条\U上Q找到它需要logn - 1ơ(败者树的最大高度ؓlognQ?<br /> <br /> 其实是一个锦标赛排序<br /> <br /> <object style="width: 499px; height: 265px" height="265" width="499" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" xcodebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab"> <param name="Movie" value="/images/blogjava_net/zellux/c9m9b.swf" /> <param name="Quality" value="high" /><param name="wmode" value="transparent" /><embed src="http://m.tkk7.com/images/blogjava_net/zellux/c9m9b.swf" width="200" height="200" quality="high" wmode="transparent" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" ></embed> </object> <img src ="http://m.tkk7.com/zellux/aggbug/150031.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/zellux/" target="_blank">ZelluX</a> 2007-10-01 11:07 <a href="http://m.tkk7.com/zellux/archive/2007/10/01/150031.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>O(n)旉求出最的k个数http://m.tkk7.com/zellux/archive/2007/09/04/142675.htmlZelluXZelluXTue, 04 Sep 2007 10:55:00 GMThttp://m.tkk7.com/zellux/archive/2007/09/04/142675.htmlhttp://m.tkk7.com/zellux/comments/142675.htmlhttp://m.tkk7.com/zellux/archive/2007/09/04/142675.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/142675.htmlhttp://m.tkk7.com/zellux/services/trackbacks/142675.html
http://en.wikipedia.org/wiki/Selection_algorithm

另外QCLRS上Selection in worst-case linear time法实际上对in expected linear time在选数时做了一个优化,q样在最差情况下也有O(n)的复杂度了,实际应用中没什么用 (thx to Peter大牛 ^_^)

ZelluX 2007-09-04 18:55 发表评论
]]>
CLRS - Lower bounds for sortinghttp://m.tkk7.com/zellux/archive/2007/09/02/142146.htmlZelluXZelluXSun, 02 Sep 2007 14:22:00 GMThttp://m.tkk7.com/zellux/archive/2007/09/02/142146.htmlhttp://m.tkk7.com/zellux/comments/142146.htmlhttp://m.tkk7.com/zellux/archive/2007/09/02/142146.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/142146.htmlhttp://m.tkk7.com/zellux/services/trackbacks/142146.html
1. 比较排序法最差情况下臛_需要omega(n lgn)
证明Q?br /> 通过决策?decision tree)分析比较排序Qn!U可能情况都要被该决{树的叶子覆盖?br /> 设树深度为hQ有
n! <= l <= 2h
得h >= lg(n!) = omega(n lgn)

2. 计数排序
很简单的排序法Q不q后面的C数组的运用比较技巧?br /> for i = 1 to k
    do c[i] = 0
for j = 1 to length(a)
    do c[a[j]] = c[a[j]] + 1
// c 数组记录了各个元素的出现ơ数
for i = 1 to k
    do c[i] = c[i] + c[i - 1]
// c[i] 记录了小于或{于i的元素个?br /> for j = length(a) downto 1
    do b[c[a[j]]] = a[j]
        c[a[j]] = c[a[j]] - 1
复杂度: k = O(n)Ӟ复杂度ؓtheta(n)

ZelluX 2007-09-02 22:22 发表评论
]]>
TopCoder SRM 144 - PowerOutagehttp://m.tkk7.com/zellux/archive/2007/08/14/136730.htmlZelluXZelluXTue, 14 Aug 2007 09:12:00 GMThttp://m.tkk7.com/zellux/archive/2007/08/14/136730.htmlhttp://m.tkk7.com/zellux/comments/136730.htmlhttp://m.tkk7.com/zellux/archive/2007/08/14/136730.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/136730.htmlhttp://m.tkk7.com/zellux/services/trackbacks/136730.html
后来才发现是在一|中,而且是从根节点出发,q个q单多?br>把所有\径加h乘以2Q就是从根节点到各个路径后再q回根节Ҏ需的最短耗费?br>然后再减掉访问最后一个节点后q回所需的耗费卛_Q既然要求最的耗费减去耗费最大的路径卛_?br>
public class PowerOutage {
    
public static int estimateTimeOut(int[] fromJunction, int[] toJunction, int[] ductLength) {
        
int sum = 0;

        
for (int i = 0; i < ductLength.length; i++)
            sum 
+= ductLength[i];
        
        sum 
*= 2;
        sum 
-= findLongestWay(0, fromJunction, toJunction, ductLength);
        
return sum;
    }

    
public static int findLongestWay(int root, int[] fromJunction,
            
int[] toJunction, int[] ductLength) {
        
int max = 0;

        
for (int i = 0; i < fromJunction.length; i++) {
            
if (fromJunction[i] == root) {
                
int temp = findLongestWay(toJunction[i], fromJunction,
                             toJunction, ductLength) 
+ ductLength[i];
                
if (temp > max)
                    max 
= temp;
            }
        }

        
return max;
    }
}




ZelluX 2007-08-14 17:12 发表评论
]]>
如何?i != i)为真http://m.tkk7.com/zellux/archive/2007/08/08/135374.htmlZelluXZelluXWed, 08 Aug 2007 15:00:00 GMThttp://m.tkk7.com/zellux/archive/2007/08/08/135374.htmlhttp://m.tkk7.com/zellux/comments/135374.htmlhttp://m.tkk7.com/zellux/archive/2007/08/08/135374.html#Feedback1http://m.tkk7.com/zellux/comments/commentRss/135374.htmlhttp://m.tkk7.com/zellux/services/trackbacks/135374.htmlwhile (i != i) {}
问如何给i赋gɽE序q入d@?br>
一U正答案是
当i为Q点类型,且gؓNAN?/span>
例如
float i = -1;
i = sqrt(i);




ZelluX 2007-08-08 23:00 发表评论
]]>
U黑?(1)http://m.tkk7.com/zellux/archive/2007/08/01/133681.htmlZelluXZelluXTue, 31 Jul 2007 16:01:00 GMThttp://m.tkk7.com/zellux/archive/2007/08/01/133681.htmlhttp://m.tkk7.com/zellux/comments/133681.htmlhttp://m.tkk7.com/zellux/archive/2007/08/01/133681.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/133681.htmlhttp://m.tkk7.com/zellux/services/trackbacks/133681.htmlhttp://zh.wikipedia.org/wiki/%E7%B4%85%E9%BB%91%E6%A8%B9

U黑?/strong>是一U?a class="new" title="自^衡二叉查找树">自^衡二叉查找树Q是?a title="计算机科?>计算机科?/a>中用到的一U?a title="数据l构">数据l构Q典型的用途是实现兌数组。它是在Rudolf Bayer发明的,他称之ؓ"对称二叉B?Q它C的名字是?Leo J. Guibas ?Robert Sedgewick ?a title="1978q?>1978q?/a>写的一论文中获得的。它是复杂的Q但它的操作有着良好的最坏情?a class="new" title="法分析">q行旉Qƈ且在实践中是高效? 它可以在O(log n)旉内做查找Q插入和删除Q这里的n是树中元素的数目?

用途和好处

U黑树和x应用(real time application)中有价|而且使它们有在提供最坏情冉|保的其他数据l构中作为徏造板块的价|例如Q在计算几何中用的很多数据l构都可以基于红黑树?/p>

U黑树在持久数据l构之一Q它们用来构?a class="new" title="兌数组">兌数组?a class="new" title="集合(计算机科?">集合Q在H变之后它们能保持ؓ以前的版本。除了O(log n)的时间之外,U黑树的持久版本Ҏơ插入或删除需要O(log n)的空间?/p>

U黑树是 二叉查找?/a>Q颜色或U色?em>黑色。在二叉查找树强制一般要求以外,对于M有效的红黑树我们增加了如下的额外要求:

性质1. 节点是红色或黑色?/p>

性质2. Ҏ黑色?/p>

性质3. 所有叶子都是黑Ԍ包括NILQ?/p>

性质4. 每个U色节点的两个子节点都是黑色?从每个叶子到根的所有\径上不能有两个连l的U色节点)

性质5. 从Q一节点到其每个叶子的所有\径都包含相同数目的黑色节炏V?/p>

q些U束强制了红黑树的关键性质: 从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。结果是q个树大致上是^衡的。因为操作比如插入、删除和查找某个值的最坏情冉|间都要求与树? 高度成比例,q个在高度上的理Z限允许红黑树在最坏情况下都是高效的,而不同于普通的

操作

因ؓ每一个红黑树也是一个特化的二叉查找?/a>上的只读操作相同。然而,在红黑树上进行插入操作和删除操作会导致不再符合红黑树的性质。恢复红黑树的属性需要少?O(log n))的颜色变?实际是非常快速的)和不过三次以二叉查找树的方?/a>? 加节点ƈ标记它ؓU色。(如果设ؓ黑色Q就会导致根到叶子的路径上有一条\上,多一个额外的黑节点,q个是很难调整的。但是设为红色节点后Q可能会D? C个连l红色节点的冲突Q那么可以通过颜色调换Qcolor flipsQ和树旋转来调整。) 下面要进行什么操作取决于其他临近节点的颜艌Ӏ同人类的家族树中一P我们用术?em>叔父节点来指一个节点的父节点的兄弟节点。注?

  • 性质1[1]和性质3[2]L保持着?/li>
  • 性质4[3]只在增加U色节点、重l黑色节点ؓU色Q或做旋转时受到威胁?/li>
  • 性质5[4]只在增加黑色节点、重l红色节点ؓ黑色Q或做旋转时受到威胁?/li>

在下面的C意图中Q将要插入的节点标ؓNQ?strong>N的父节点标ؓPQ?strong>N的祖父节Ҏ?strong>GQ?strong>N的叔父节Ҏ?strong>U。在图中展示的Q何颜色要么是由它所处情形所作的假定Q要么是q些假定所暗含的?/p>

对于每一U情况,我们?CCZ代码来展C。通过下列函数Q可以找C个节点的叔父和祖父节?

node grandparent(node n) {
return n->parent->parent;
}

node uncle(node n) {
if (n->parent == grandparent(n)->left)
return grandparent(n)->right;
else
return grandparent(n)->left;
}

情Ş1: 新节?strong>N位于树的根上Q没有父节点。在q种情Ş下,我们把它重绘为黑色以满性质2[5]。因为它在每个\径上寚w节点数目增加一Q性质5[4]W合?/p>

void insert_case1(node n) {
if (n->parent == NULL)
n->color = BLACK;
else
insert_case2(n);
}

情Ş2: 新节点的父节?strong>P是黑Ԍ所以性质4[3]没有失效Q新节点是红色的Q。在q种情Ş下,树仍是有效的。性质5[4]受到威胁Q因为新节点N有两个黑色叶子儿子;但是׃新节?strong>N是红Ԍ通过它的每个子节点的路径都有同通过它所取代的黑色的叶子的\径同h目的黑色节点Q所以这个性质依然满?/p>

void insert_case2(node n) {
if (n->parent->color == BLACK)
return; /* 树仍旧有?*/
else
insert_case3(n);
}

注意: 在下列情形下我们假定新节Ҏ父节点Q因为父节点是红Ԍq且如果它是根,它就应当是黑艌Ӏ所以新节点L一个叔父节点,管在情??下它可能是叶子?/p>

情Ş3: 如果父节?strong>P和叔父节?strong>U二者都是红Ԍ则我们可以将它们两个重绘为黑色ƈ重绘父节点G为红?用来保持性质5[4])。现在我们的新节?strong>N有了一个黑色的父节?strong>P。因为通过父节?strong>P或叔父节?strong>U的Q何\径都必定通过父节点GQ在q些路径上的黑节Ҏ目没有改变。但是,U色的祖父节?strong>G的父节点也有可能是红色的Q这p反了性质4[3]。ؓ了解册个问题,我们在祖父节?strong>G上递归地进?strong>情Ş1的整个过E?/p>

void insert_case3(node n) {
if (uncle(n) != NULL && uncle(n)->color == RED) {
n->parent->color = BLACK;
uncle(n)->color = BLACK;
grandparent(n)->color = RED;
insert_case1(grandparent(n));
}
else
insert_case4(n);
}

注意: 在余下的情Ş下,我们假定父节?strong>P 是其父亲G 的左子节炏V如果它是右子节点,情Ş4?strong>情Ş5中的?/em>?em>?/em>应当对调?/p>

情Ş4: 父节?strong>P是红色而叔父节?strong>U是黑色或~少; q有Q新节点N是其父节?strong>P的右子节点,而父节点P又是其父节点的左子节炏V在q种情Ş下,我们q行一?a class="new" title="树旋?>左旋?/a>调换新节点和其父节点的角? 接着Q我们按情Ş5处理以前的父节点P。这D某些路径通过它们以前不通过的新节点N或父节点P中的一个,但是q两个节炚w是红色的Q所以性质5[4]没有失效?/p>

void insert_case4(node n) {
if (n == n->parent->right && n->parent == grandparent(n)->left) {
rotate_left(n->parent);
n = n->left;
} else if (n == n->parent->left && n->parent == grandparent(n)->right) {
rotate_right(n->parent);
n = n->right;
}
insert_case5(n);
}

情Ş5: 父节?strong>P是红色而叔父节?strong>U 是黑色或~少Q新节点N 是其父节点的左子节点Q而父节点P又是其父节点G的左子节炏V在q种情Ş下,我们q行针对父节点P 的一?a class="new" title="树旋?>x?/a>; 在旋转生的树中Q以前的父节?strong>P现在是新节点N和以前的父节点G 的父节点。我们知道以前的父节点G是黑Ԍ否则父节?strong>P׃可能是红艌Ӏ我们切换以前的父节?strong>P和祖父节?strong>G的颜Ԍl果的树满性质4[3]。性质5[4]也仍然保持满I因ؓ通过q三个节点中M一个的所有\径以前都通过父节点G Q现在它们都通过以前的父节点P。在各自的情形下Q这都是三个节点中唯一的黑色节炏V?/p>

void insert_case5(node n) {
n->parent->color = BLACK;
grandparent(n)->color = RED;
if (n == n->parent->left && n->parent == grandparent(n)->left) {
rotate_right(grandparent(n));
} else {
/* Here, n == n->parent->right && n->parent == grandparent(n)->right */
rotate_left(grandparent(n));
}
}

注意插入实际上是原地法Q因Zq所有调用都使用?a class="new" title="N递归">N递归?/p>

[~辑] 删除

如果需要删除的节点有两个儿子,那么问题可以被{化成删除另一个只有一个儿子的节点的问?/strong>Qؓ了表q方便,q里所指的儿子Qؓ非叶子节点的儿子Q。对于二叉查找树Q在删除带有两个非叶子儿子的节点的时候,我们扑ֈ要么在它的左子树中的最大元素、要么在它的叛_树中的最元素,q把它的D{Ud要删除的节点?如在q里所展示的那?。我们接着删除我们从中复制出值的那个节点Q它必定有少于两个非叶子的儿子。因为只是复制了一个D不q反M属性,q就把问题简化ؓ如何删除最多有一个儿子的节点的问题。它不关心这个节Ҏ最初要删除的节点还是我们从中复制出值的那个节点?/p>

在本文余下的部分中,我们只需要讨论删除只有一个儿子的节点(如果它两个儿子都为空Q即均ؓ叶子Q我们Q意将其中一个看作它的儿 ?。如果我们删除一个红色节点,它的父亲和儿子一定是黑色的。所以我们可以简单的用它的黑色儿子替换它Qƈ不会破坏属??。通过被删除节点的所有\ 径只是少了一个红色节点,q样可以l箋保证属?。另一U简单情冉|在被删除节点是黑色而它的儿子是U色的时候。如果只是去除这个黑色节点,用它的红色儿 子顶替上来的话,会破坏属?Q但是如果我们重l它的儿子ؓ黑色Q则曄通过它的所有\径将通过它的黑色儿子Q这样可以l保持属??/p>

需要进一步讨论的是在要删除的节点和它的儿子二者都是黑色的时?/strong>Q这是一U复杂的情况。我们首先把要删除的节点替换为它的儿子。出于方便,U呼q个儿子?strong>NQ称呼它的兄?它父亲的另一个儿??strong>S。在下面的示意图中,我们q是使用PU呼N的父ԌSLU呼S的左儿子QSRU呼S的右儿子。我们将使用下述函数扑ֈ兄弟节点:

node sibling(node n) {
if (n == n->parent->left)
return n->parent->right;
else
return n->parent->left;
}

我们可以使用下列代码q行上述的概要步骤,q里的函?replace_node 替换 child ?n 在树中的位置。出于方便,在本章节中的代码假定空叶子被用不是 NULL 的实际节点对象来表示(?em>插入章节中的代码可以同Q何一U表CZ起工??/p>

void delete_one_child(node n) {
/* Precondition: n has at most one non-null child */
node child = (is_leaf(n->right)) ? n->left : n->right;
replace_node(n, child);
if (n->color == BLACK) {
if (child->color == RED)
child->color = BLACK;
else
delete_case1(child);
}
free(n);
}

如果 N 和它初始的父亲是黑色Q则删除它的父亲D通过 N 的\径都比不通过它的路径了一个黑色节炏V因q反了属?4Q树需要被重新q。有几种情况需要考虑:

情况 1: N 是新的根。在q种情况下,我们做完了。我们从所有\径去除了一个黑色节点,而新Ҏ黑色的,所以属性都保持着?/p>

void delete_case1(node n) {
if (n->parent == NULL)
return;
else
delete_case2(n);
}

注意: 在情???下,我们假定 N 是它父亲的左儿子。如果它是右儿子Q则在这些情况下?em>?/em>?em>?/em>应当对调?/p>

情况 2: S 是红艌Ӏ在q种情况下我们在N的父亲上做左旋{Q把U色兄弟转换成N的祖父。我们接着对调 N 的父亲和父的颜艌Ӏ尽所有的路径仍然有相同数目的黑色节点Q现?N 有了一个黑色的兄弟和一个红色的父亲Q所以我们可以接下去?4??情况来处理?它的新兄弟是黑色因ؓ它是U色S的一个儿子?

void delete_case2(node n) {
if (sibling(n)->color == RED) {
n->parent->color = RED;
sibling(n)->color = BLACK;
if (n == n->parent->left)
rotate_left(n->parent);
else
rotate_right(n->parent);
}
delete_case3(n);
}

情况 3: N 的父二ӀS ?S 的儿子都是黑色的。在q种情况下,我们单的重绘 S 为红艌Ӏ结果是通过S的所有\? 它们是以前?/em>? q?N 的那些\径,都少了一个黑色节炏V因为删?N 的初始的父亲佉K过 N 的所有\径少了一个黑色节点,q事情都^衡了h。但是,通过 P 的所有\径现在比不通过 P 的\径少了一个黑色节点,所以仍然违反属?。要修正q个问题Q我们要从情?1 开始,?P 上做重新q处理?/p>

void delete_case3(node n) {
if (n->parent->color == BLACK &&
sibling(n)->color == BLACK &&
sibling(n)->left->color == BLACK &&
sibling(n)->right->color == BLACK)
{
sibling(n)->color = RED;
delete_case1(n->parent);
}
else
delete_case4(n);
}

情况 4: S ?S 的儿子都是黑Ԍ但是 N 的父亲是U色。在q种情况下,我们单的交换 N 的兄弟和父亲的颜艌Ӏ这不媄响不通过 N 的\径的黑色节点的数目,但是它在通过 N 的\径上寚w色节Ҏ目增加了一Q添补了在这些\径上删除的黑色节炏V?/p>

void delete_case4(node n) {
if (n->parent->color == RED &&
sibling(n)->color == BLACK &&
sibling(n)->left->color == BLACK &&
sibling(n)->right->color == BLACK)
{
sibling(n)->color = RED;
n->parent->color = BLACK;
}
else
delete_case5(n);
}

情况 5: S 是黑ԌS 的左儿子是红ԌS 的右儿子是黑Ԍ?N 是它父亲的左儿子。在q种情况下我们在 S 上做x转,q样 S 的左儿子成ؓ S 的父亲和 N 的新兄弟。我们接着交换 S 和它的新父亲的颜艌Ӏ所有\径仍有同h目的黑色节点Q但是现? N 有了一个右儿子是红色的黑色兄弟Q所以我们进入了情况 6。N 和它的父亲都不受q个变换的媄响?/p>

void delete_case5(node n) {
if (n == n->parent->left &&
sibling(n)->color == BLACK &&
sibling(n)->left->color == RED &&
sibling(n)->right->color == BLACK)
{
sibling(n)->color = RED;
sibling(n)->left->color = BLACK;
rotate_right(sibling(n));
}
else if (n == n->parent->right &&
sibling(n)->color == BLACK &&
sibling(n)->right->color == RED &&
sibling(n)->left->color == BLACK)
{
sibling(n)->color = RED;
sibling(n)->right->color = BLACK;
rotate_left(sibling(n));
}
delete_case6(n);
}

情况 6: S 是黑ԌS 的右儿子是红Ԍ?N 是它父亲的左儿子。在q种情况下我们在 N 的父亲上做左旋{Q这?S 成ؓ N 的父亲和 S 的右儿子的父二Ӏ我们接着交换 N 的父亲和 S 的颜Ԍq S 的右儿子为黑艌Ӏ子树在它的根上的仍是同L颜色Q所以属?3 没有被违反。但是,N 现在增加了一个黑色祖? 要ُ N 的父亲变成黑Ԍ要么它是黑色?S 被增加ؓ一个黑色祖父。所以,通过 N 的\径都增加了一个黑色节炏V?/p>

此时Q如果一个\径不通过 NQ则有两U可能?

  • 它通过 N 的新兄弟。那么它以前和现在都必定通过 S ?N 的父Ԍ而它们只是交换了颜色。所以\径保持了同样数目的黑色节炏V?/li>
  • 它通过 N 的新叔父QS 的右儿子。那么它以前通过 S、S 的父亲和 S 的右儿子Q但是现在只通过 SQ它被假定ؓ它以前的父亲的颜Ԍ?S 的右儿子Q它被从U色改变为黑艌Ӏ合成效果是q个路径通过了同h目的黑色节点?/li>

在Q何情况下Q在q些路径上的黑色节点数目都没有改变。所以我们恢复了属?4。在C意图中的白色节点可以是U色或黑Ԍ但是在变换前后都必须指定相同的颜艌Ӏ?/p>

void delete_case6(node n) {
sibling(n)->color = n->parent->color;
n->parent->color = BLACK;
if (n == n->parent->left) {
/* Here, sibling(n)->color == BLACK &&
sibling(n)->right->color == RED */
sibling(n)->right->color = BLACK;
rotate_left(n->parent);
}
else
{
/* Here, sibling(n)->color == BLACK &&
sibling(n)->left->color == RED */
sibling(n)->left->color = BLACK;
rotate_right(n->parent);
}
}

同样的,函数调用都用了N递归Q所以算法是地?/a>。此外,在旋转之后不再做递归调用Q所以进行了恒定数目(最?3 ?的旋转?/p>


渐进边界的证?/h2>

包含n个内部节点的U黑树的高度?O(log(n))?/p>

定义:

  • h(v) = 以节?em>v为根的子树的高度?/li>
  • bh(v) = ?em>v到子树中M叶子的黑色节点的数目(如果v是黑色则不计数它)(也叫做黑色高??/li>

引理: 以节?em>v为根的子树有臛_2bh(v) − 1个内部节炏V?/p>

引理的证?通过归纳高度):

基础: h(v) = 0

如果v的高度是零则它必定是 nilQ因?bh(v) = 0。所?

2bh(v) − 1 = 20 − 1 = 1 − 1 = 0

归纳假设: h(v) = k ?em>v?2bh(v) − 1 − 1 个内部节ҎCZ h(v') = k+1 ?v'?bh(v') − 1 个内部节炏V?/p>

因ؓ v' ?h(v') > 0 所以它是个内部节点。同L它有黑色高度要么?bh(v') 要么?bh(v')-1 (依据v'是红色还是黑?的两个儿子。通过归纳假设每个儿子都有臛_ 2bh(v') − 1 − 1 个内部接点,所?v' ?

2bh(v') − 1 − 1 + 2bh(v') − 1 − 1 + 1 = 2bh(v') − 1

个内部节炏V?/p>

使用q个引理我们现在可以展示出树的高度是Ҏ性的。因为在从根到叶子的M路径上至有一半的节点是黑?ҎU黑树属?)Q根的黑色高度至是h(root)/2。通过引理我们得到:

n \geq 2^{{h(root) \over 2}} - 1 \leftrightarrow \; \log{(n+1)} \geq {h(root) \over 2} \leftrightarrow \; h(root) \leq 2\log{(n+1)}

因此根的高度是O(log(n))?/p>

ZelluX 2007-08-01 00:01 发表评论
]]>全排列的非递归版本http://m.tkk7.com/zellux/archive/2007/07/31/133540.htmlZelluXZelluXTue, 31 Jul 2007 03:58:00 GMThttp://m.tkk7.com/zellux/archive/2007/07/31/133540.htmlhttp://m.tkk7.com/zellux/comments/133540.htmlhttp://m.tkk7.com/zellux/archive/2007/07/31/133540.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/133540.htmlhttp://m.tkk7.com/zellux/services/trackbacks/133540.htmlfrom smth.org

= malloc(n * sizeof(int));
for (i = 0; i < n; i++)
   p[i] 
= i;

output(p, n);

for (i = n - 1; i > 0; i--)
   
if (p[i] > p[i - 1])
   {
      
for (j = n - 1; p[j] < p[i - 1]; j--);
      swap(
&(p[i - 1]), &(p[j]));

      
for (j = i, k = n - 1; j < k; j++, k--)
         swap(
&(p[j]), &(p[k]));

      ouput(p, n);
      i 
= n;
   }

free(p);



ZelluX 2007-07-31 11:58 发表评论
]]>
PKU 1014 Dividinghttp://m.tkk7.com/zellux/archive/2007/07/30/133416.htmlZelluXZelluXMon, 30 Jul 2007 11:59:00 GMThttp://m.tkk7.com/zellux/archive/2007/07/30/133416.htmlhttp://m.tkk7.com/zellux/comments/133416.htmlhttp://m.tkk7.com/zellux/archive/2007/07/30/133416.html#Feedback1http://m.tkk7.com/zellux/comments/commentRss/133416.htmlhttp://m.tkk7.com/zellux/services/trackbacks/133416.html 扑ֈ一个优化方案,l果0msp了,orz
http://162.105.81.202/course/problemSolving/dividingProve.doc
以下均{自这文章?br> l论 对于L一U珠宝的个数nQ如果n>=8, 可以n改写?11Qn为奇敎ͼ ?12Qn为偶敎ͼ?br>
证明Q?br>
对于L一l数Q?的个Cؓn(n>=8)

一、如果可以分成两堆,我们可以分成两种情况Q?br>   1.
      两堆里都?Q那么我们可知:把n改ؓn-2Q仍然可分?br>(两堆各减一?)
2. 只有一堆里?Q设为左边,那么左边的d不小?*8=48?br>我们观察Q?*6=6*5 Q?*3=6*2 Q?3*2=6 Q?2*3=6 Q?1*6=6
?5*5 + 4*2 + 3*1 + 2*2 + 1*5 = 25 + 8 + 3 + 4 + 5 = 45 < 48
由抽屉原理右边必然存?br>(多于5个的5 或?多于2个的4 或?多于1个的3
或?多于2个的2 或?多于5个的1)
卛_边至存在一l数的和{于若干?Q比如右Ҏ3?Q这h左边??与右边的3?交换Q则又出现左右都?的情c?Ҏ1Q我们还是可以把n改ؓn-2且可分的状态不变?br>l合1Q?。我们可以看出只要原来n的个?8,我们可以把它改为n-2Q这h作一直进行到n<8。我们可以得出结论,对于大于{于8的偶敎ͼ可以换成6?br>对于大于8的奇敎ͼ可以换成7。换完之后仍然可分?br>
二、如果不能分成两堆:
昄改ؓn-2时同样也不能分,那么对于大于{于8的偶敎ͼ可以换成6Q对于大?的奇敎ͼ可以换成7。换完之后仍然不可分?br>
l合一、二Q我们得出结论把不小?的偶数改?Q大?的奇数改?Q原来可分与否的性质不会改变?br>
以上是对6的讨论,同样的方法可以推?br>5的个?6*4 + 4*4 + 3*4 + 2*4 + 1*4 = 64 < 5*13
?的个数多?2Ӟ偶数换ؓ12Q奇数换?1
4的个?6*1 + 5*3 + 3*3 + 2*1 + 1*3 = 35 < 4*9
?的个数多?Ӟ偶数换ؓ8Q奇数换?
3的个?5*2 + 4*2 + 2*2 + 1*2 = 24 < 3*9
?的个数多?Ӟ偶数换ؓ8Q奇数换?
2的个?5*1 + 3*1 + 1*1 = 9 < 2*5
?的个数多?Ӟ偶数换ؓ4Q奇数换?
1的个?多于5则必然可?在L是偶数的前提?

lg所q?
对于L一U珠宝的个数nQ如果n>=8, 可以n改写?11Qn为奇敎ͼ ?12Qn为偶敎ͼ?br>
q一步分析:
Ҏ个数Q?-6Q,以上只是_略的估计,可以q一步减其最大有效取|例如Q?br>对于6Q?*5 + 4*2 + 3*1 + 2*2 + 1*5 = 25 + 8 + 3 + 4 + 5 = 45
有4?不能同时出现Q??不能同时出现Q????不能同时出现Q??不能??同时出现{等Q所以组合不?的整数倍的情况的MhD多ؓ25Q所以当6的个数大?Ӟ奇数可改?Q偶数可改ؓ6?br>1-5 也有cM情况?br>
Z得出_|下面先我们讨样一个数论命题?br>
命题Q?br>可重复的从自然数集中取出n个数Qn>=2)Q其中必有若q个C和能被n整除?br>
证明Q设取出的n个自然数为a1,a2,a3,.....an

考虑q样的n+1个数 0, a1, a1+a2 , a1+a2+a3 , ...... , a1+a2+a3+...+anQ?׃自然数模n的剩余类有n个,所以以上n+1个数中必有两个同余?q两个数的差必被n整除Q而且q两个数的差是原来的n个数中的一些数的和?br>q就证明了命题?br>
׃上命?br>对于6而言Q我们至多从{1Q?Q?Q?Q?}中可重复的找?个数使它们不能组合成6的倍数?br>所以这些数的和于{于5*5=25
对于5而言Q我们至多从{1Q?Q?Q?Q?}中可重复的找?个数使它们不能组合成5的倍数?br>所以这些数的和于{于6*4=24
对于4而言Q我们至多从{1Q?Q?Q?Q?}中可重复的找?个数使它们不能组合成4的倍数?br>所以这些数的和于{于3*6=18 Q?然而,两个6是4的倍数Q?所以最多有一?
此时不能有两?Q?*5+6=16?的倍数Q, 最多才6 + 5 + 3 = 14 < 3*5 =15
所以这些数的和于{于3*5=15
对于3而言Q我们至多从{1Q?Q?Q?Q?}中可重复的找?个数使它们不能组合成3的倍数?br>所以这些数的和于{于2*5=10

Q?是3的倍数Q所以不能取6Q?br>
对于2而言Q我们至多从{1Q?Q?Q?Q?}中可重复的找?个数使它们不能组合成6的倍数?br>
所以这些数的和于{于1*5=5



考虑?4*6 < 25 < 5*6 , 我们可以出6的最大有效个Cؓ5 ?br>
考虑?4*5 < 24 < 5*5 , 我们可以出5的最大有效个Cؓ5 。但是其实应该修正ؓ6Q?如果遇到如下Ҏ情况Q左??Q右??。此时虽然左叛_以交换,但是交换后仍然只有一Ҏ5Q与Q一?Q中讨论情况不符?br>
考虑?3*4 < 15 < 4*4 , 我们可以出5的最大有效个Cؓ4 。但是其实应该修正ؓ5Q?如果遇到如下Ҏ情况Q左??Q右??。此时虽然左叛_以交换,但是交换后仍然只有一Ҏ4Q与Q一?Q中讨论情况不符?br>
考虑?3*3 < 10 < 4*3 , 我们可以出5的最大有效个Cؓ4 。但是其实应该修正ؓ5Q?如果遇到如下Ҏ情况Q左??Q右??。此时虽然左叛_以交换,但是交换后仍然只有一Ҏ3Q与Q一?Q中讨论情况不符?br>
考虑?2*2 < 5 < 3*2 , 我们可以出5的最大有效个Cؓ3 ?但是其实应该修正?Q如果遇到如下特D情况,左边1???Q右??。此时虽然左叛_以交换,但是交换后仍然只有一Ҏ2Q与Q一?Q中讨论情况不符?br>

我们得出最后的_l论Q?br>
奇数改ؓ 偶数改ؓ
6的个数大? 5 4
5的个数大? 5 6
4的个数大? 5 4
3的个数大? 5 4
2的个数大? 3 4 



优化后的代码Q?br>
#include <iostream>
using namespace std;

long n[6];
long sum;
const long MAX_N = 60000;

int dividable()
{
    
int f[MAX_N];
    
for (int i = 0; i <= sum; i++)
        f[i] 
= 0;
    f[
0= 1;
    
for (int i = 0; i < 6; i++)
    {
        
for (int j = 1; j <= n[i]; j++)
        {
            
int base = j * (i + 1);
            
if (base > sum) break;
            
for (int k = sum - (i+1); k >= base - i - 1; k--)
                
if (f[k])
                    f[k 
+ i + 1= 1;
            
if (f[sum]) return 1;
        }
    }
    
return f[sum];
}

int main()
{
    
long cases = 0;
    
while (true)
    {
        sum 
= 0;
        
for (long i = 0; i < 6; i++)
        {
            cin 
>> n[i];
        }
        
if (n[5> 5) n[5= 4 + n[5% 2;
        
if (n[4> 6) n[4= 6 - n[4% 2;
        
if (n[3> 5) n[3= 4 + n[3% 2;
        
if (n[2> 5) n[2= 4 + n[2% 2;
        
if (n[1> 4) n[1= 4 - n[1% 2;
        
for (long i = 0; i < 6; i++)
        {
            sum 
+= n[i] * (i + 1);
        }
        
if (sum == 0)
            
break;
        cases
++;
        cout 
<< "Collection #" << cases << ":\n";
        
if (sum % 2 != 0)
        {
            cout 
<< "Can't be divided.\n\n";
            
continue;
        }
        sum 
/= 2;
        
if (dividable())
            cout 
<< "Can be divided.\n";
        
else
            cout 
<< "Can't be divided.\n";
        cout 
<< endl;
    }
    
return 0;
}




ZelluX 2007-07-30 19:59 发表评论
]]>
Nuts-and-Bolts Problemhttp://m.tkk7.com/zellux/archive/2007/07/25/132328.htmlZelluXZelluXWed, 25 Jul 2007 08:01:00 GMThttp://m.tkk7.com/zellux/archive/2007/07/25/132328.htmlhttp://m.tkk7.com/zellux/comments/132328.htmlhttp://m.tkk7.com/zellux/archive/2007/07/25/132328.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/132328.htmlhttp://m.tkk7.com/zellux/services/trackbacks/132328.html问题Q?/p>

有n个大各不相同的螺帽及对应的螺钉Q要求在O(nlogn)的复杂度内完成配寏V螺钉之间、螺帽之间都无法直接比较大小Q只能比较一颗螺帽与螺钉Q判断他们之间的大小差异?br>

感觉和快速排序的partition差不多?/p>

首先任选一颗螺钉与各螺帽进行比较,分成大小两组Q另外得C改螺钉相匚w的螺帽?/p>

然后用那个螺帽再和其他螺钉比较,也分成大两l,然后l箋二分递归?/p>

 

 



ZelluX 2007-07-25 16:01 发表评论
]]>
Stooge sorthttp://m.tkk7.com/zellux/archive/2007/07/25/132295.htmlZelluXZelluXWed, 25 Jul 2007 06:13:00 GMThttp://m.tkk7.com/zellux/archive/2007/07/25/132295.htmlhttp://m.tkk7.com/zellux/comments/132295.htmlhttp://m.tkk7.com/zellux/archive/2007/07/25/132295.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/132295.htmlhttp://m.tkk7.com/zellux/services/trackbacks/132295.html伪代码描qͼ
Stooge-sort(A, i, j)
if A[i] > A[j]
    then exchange A[i], A[]
if i + 1  >= j
    then return
k = (j - i + 1) / 3
Stooge-sort(A, i, j - k)
Stooge-sort(A, i + k , j)
Stooge-sort(A, i, j - k)
卛_排序?/3部分Q然后是?/3部分Q最后再q行前面1/3的排序?br>
a. 证明法正确?br>׃是递归法Q而初始状态显然成立,因此只要证明当部分排序正时Q整体也能够被正排序:
W一ơ排序后Q第二部分每个数都不于W一部分的所有数Q?br>W二ơ排序后Q第二部分某些数被交换到W三部分中,此时W三部分数都不小于第二部分和W一部分的数Q但是第二部分的数ƈ不一定都于W一部分的(因ؓ可能包含W三部分的数Q而这些数与第一部分数的大小关系无法认Q;
W三ơ排序后Q第二部分的数都不小于第一部分的数?br>q样Q第一部分的Q意数<=W二部分的Q意数<=W三部分的Q意数
而且各部分的数都已排序,因此整体已被排序?br>
b. 复杂度分?br>递归?br>T(n) = 3T(2n/3) + 1
由Master Theorem

T(n) = O(n^log(3/2, 3))


ZelluX 2007-07-25 14:13 发表评论
]]>
Young tableaushttp://m.tkk7.com/zellux/archive/2007/07/23/131922.htmlZelluXZelluXMon, 23 Jul 2007 09:51:00 GMThttp://m.tkk7.com/zellux/archive/2007/07/23/131922.htmlhttp://m.tkk7.com/zellux/comments/131922.htmlhttp://m.tkk7.com/zellux/archive/2007/07/23/131922.html#Feedback0http://m.tkk7.com/zellux/comments/commentRss/131922.htmlhttp://m.tkk7.com/zellux/services/trackbacks/131922.html
/* Min-Young tableaus on Page 143 */
#include 
<iostream>
#include 
<iomanip>
using namespace std;

template 
<class Type>
class YTable
{
private:
    Type
** data;
    
int m, n;
    
const static int INFINITY = 9999;
public:
    YTable(
int m = 10int n = 10);
    
~YTable();
    
int Insert(Type x);
    
int FloatUp(int x, int y);
    
int Print();
    
int Extract(int x, int y, Type value);
};

template 
<class Type>
YTable
<Type>::YTable(int m, int n)
{
    
this->= m;
    
this->= n;
    data 
= new Type*[m];
    
for (int i = 0; i < m; i++)
        data[i] 
= new Type[n];
    
for (int i = 0; i < m; i++)
        
for (int j = 0; j < n; j++)
            data[i][j] 
= INFINITY;
}

template 
<class Type>
YTable
<Type>::~YTable()
{
    
for (int i = 0; i < m; i++)
        delete [] data[i];
    delete [] data;
}

template 
<class Type>
int YTable<Type>::Insert(Type x)
{
    
if (data[m - 1][n - 1!= INFINITY)
        
return 0;
    data[m 
- 1][n - 1= x;
    FloatUp(m 
- 1, n - 1);
    
return 1;
}

template 
<class Type>
int YTable<Type>::FloatUp(int x, int y)
{
    
int maxX = x;
    
int maxY = y;
    
if (x > 0 && data[x - 1][y] > data[maxX][maxY])
    {
        maxX 
= x - 1;
        maxY 
= y;
    }
    
if (y > 0 && data[x][y - 1> data[maxX][maxY])
    {
        maxX 
= x;
        maxY 
= y - 1;
    }
    
if (maxX != x || maxY != y)
    {
        swap(data[maxX][maxY], data[x][y]);
        FloatUp(maxX, maxY);
    }
    
return 1;
}

template 
<class Type>
int YTable<Type>::Print()
{
    cout.setf(ios::
fixed);
    
for (int i = 0; i < m; i++)
    {
        
for (int j = 0; j < n; j++)
            
if (data[i][j] != INFINITY)
                cout 
<< setw(3<< data[i][j];
            
else
                cout 
<< " X ";
        cout 
<< endl;
    }
    
return 1;
}

template 
<class Type>
int YTable<Type>::Extract(int x, int y, Type value)
{
    data[x][y] 
= value;
    FloatUp(x, y);
    
return 1;
}

int main()
{
    YTable
<int> myTable(44);
    
int x[] = {91632481514127111015136};
    
for (int i = 0; i < 16; i++)
        myTable.Insert(x[i]);
    cout 
<< "Initial state:\n";
    myTable.Print();
    cout 
<< "\nNow change (4,3) to 5:\n";
    myTable.Extract(
325);
    myTable.Print();
    
return 0;
}
    




ZelluX 2007-07-23 17:51 发表评论
]]>
վ֩ģ壺 ˾þۺӰԺ| ഺɫƷ| avҹƷһ| ް鵺̳| ӰԺ| ɫվwww| ݾ߹ۿվ| ȫƵ߹ۿ| 1000Ƶ| aëƬ| ޹Ӱavַ| պ޴߶ȸ| ޸һ| ޾ƷaĻ| ɫëƬƵ| þùһ| Ƶ߹ۿѿƬ| ޾Ʒ˾߹ۿ| պߵӰ| AVһ| 91µַ| 18վڵ| ŷ͵Ʒ | Ƶ߲| 337Pձŷ޴ͼ| ѿؼëƬ| վƵA˫| ˾þۺӰԺ| þúݺݸ߳޾Ʒ| ˾ҹƵ| 99Ƶ߾Ʒ| ѹھƷþþþӰԺ| þù޹ۿ| AVպAVһ| ˾Ʒһ| ŮݽƵѿ| AVһȾþ| Ʒ޹av| þùѹۿƷ3| ۺƷ͵| ɫͼɫС˵|