1. 在Intel 多核CPU上, 以下多线程对int型变量x的操作,哪几个不是原子操作,假定变量的地址都是对齐的.
A. x=y B. - -x C. x-=1 D. x=-1 E.x-=y
2. 下面程序的输出结果:
#include <iostream> using namespace std; class A{ public: A(){} ~A(){} int f1(int a){ cout<<"Base f1"; return 0; } virtual int g1(int a){ cout<<"Base g1 int"; return 0; } int g1(short a){ cout<<"Base g1 short"; return 0; } }; class B:public A{ public: B(){} ~B(){} int f1(int a){ cout<<"Derived f1"; return 0; } int g1(int a){ cout<<"Derived g1 int"; return 0; } virtual int g1(short a){ cout<<"Derived g1 short"; return 0; } }; int main(){ A* p1=new B; (*p1).g1(short(1));cout<<','; p1->g1(1);cout<<','; ((A)(*p1)).f1(1);cout<<'\n'; return 0; }
输出结果为:
Base g1 short,Derived g1 int,Base f1
3. 虚函数是动态绑定的, 但是默认参数却是静态绑定的.
4. 稀疏矩阵
5. 假设AVL树有100个节点, 则其最大高度为:
7. 时间复杂度
8. Hash表
9.
10. 扔瓶子
有两个完全一样的瓶子,还有一幢100层的大楼。你想知道瓶子在哪一层会刚好摔碎(或者100层之内不碎),当然有可能从1层摔下就会碎,也有可能从100层摔下来也不会碎。但瓶子一旦摔碎就没法再使用了。现在要找一种方法,使得摔瓶子的次数最少。
正如原题中提到的那样,我们可以用一个瓶子,从1层开始,一层层试,这样肯定可以找到临界层,但最坏的情况是要摔100次才行。
很容易想到稍微好一些的方法:第一个瓶子从2层开始,尝试每个偶数层,直到摔碎(或者到100层也没碎,那问题就解决了),然后用剩下的一个瓶子尝试低一层,这样就可以解决问题。最坏的情况是临界层为99层,这样我们需要试51次才能得到答案,不过这已经比第一种方法好很多了。
如果我们把第一个瓶子每隔两层摔一次呢?会不会更少?
…………
先不要急着求解,让我们来想想摔瓶子需要遵守哪些原则。
首先,不管用什么方法,都应该从低层向高层尝试吧?我想没有哪个人会直接把第一个瓶子从100层摔下来,因为一旦摔碎,我们就只剩下一个瓶子了。
注意,只剩下一个瓶子的时候,就只能从已经确定的“安全楼层”开始,一层一层往上试了。所以我们很容易想到,最佳策略应该是用第一个瓶子确定一个范围,然后用第二个瓶子穷举。其实之前提到的摔偶数层的方法就是用的这个思想。
用规范一点的语言表述,就是:
如果第一个瓶子在a层没有摔碎,紧接着下一次尝试在b层(b>a)摔碎了,那么我们必须要用第二个瓶子从(a+1)层开始一层层往上试,直至摔碎,该层就是临界层。当然,如果到(b-1)层还没有碎,那么我们就知道临界层是b层了。
由于我们的策略必须要保证能找到临界层,所以我们必须以最坏情况最为衡量策略优劣的标准。我们要做的是就是把最坏情况的尝试次数降到最低。
我们来举一个例子:如果是把第一个瓶子从50层扔下来(可以说是二分法思想),会有两种情况:如果碎了,那么就必须把另一个瓶子从1楼开始试起,这种情况的最坏情况是临界层为49层或50层,需要试50次;如果没碎,这个时候我们还可以继续二分,把瓶子从75层摔下,如果碎了,那么就要从51层试起,“最坏情况”是要试到74层,总共要试26次……
当然,我们最终只有一个“最坏情况”,也就是50次,像26次这样的只能称作是“极坏情况”。
容易看出,就算极坏情况的尝试次数再少,最坏情况才是评判的标准。如果可以让最坏情况的尝试次数减少,哪怕极坏情况尝试的次数稍微增加也没问题。所以我们要做的是:
让所有的极坏情况和最坏情况的尝试次数尽可能接近。
由于第一个瓶子是用来确定穷举范围,每试一次,次数都要加1,那么为了使得总次数尽可能接近,确定的穷举范围就要少1。
于是1+2+3+…+14=105>100,所以我们第一个瓶子从14层开始摔,假如没碎的话就到27(14+13)层,然后是39(14+13+12)层,然后层数分别为50、60、69、77、84、90、95、99、100。当瓶子摔碎的时候,我们就可以知道一个范围,然后开始穷举,这样极坏情况和最坏情况都是14次!
这就是最佳方案!
当然,我是不会满足解决两个瓶子的问题的,我开始想3个瓶子的情况。后来发现3个瓶子的问题也是同样的思路:前两个瓶子用来测定范围,最后一个瓶子用来穷举。只不过数列不是1+2+3…这样,而是1+(1+2)+(1+2+3)+…+(1+2+3+4+5+6+7+8)=120>100。于是第一个从36(1+2+3+4+5+6+7+8)层摔,然后如果没碎就从64(36+1+2+3+4+5+6+7)层摔,以此类推,如果碎了就转化成了两个瓶子的问题。
参考: http://hi.baidu.com/simonkuang26/item/2572e8fd16c3066e3d14853c
11. 方格取数
12. 八哥送信