和处吃鸡多少帧才是正常的目前wwW正常的播放11xxyy入口啊,怎么现在的11xxyy变的老是com不稳定

(大明湖畔马冬梅)
第三方登录:我是开洗衣店的给你点建议,洗衣服是用肥皂清洗,然后到超市买一瓶84然后用牙刷蘸84对有污渍处刷洗,但要求是白色衣服,如果是彩色衣服就不要用84会烧掉色,彩色衣服去买一瓶彩票水倒在有污渍处反复搓洗就好了,因为彩票水是可以洗任何颜色的衣物的,是去色增艳的 kuaijie
其他答案(共17个回答)
放进去浸一会儿洗,衣服会很白
白衣服巧洗保洁白 ◆ 滴墨水法:在一盆干净的凉水中,滴3-5滴纯蓝墨水,用手搅匀,然后把洗漂干净的白衬衫放进水中,上下提拉3-5次,捞出晾干。 ◆ 加双氧水法:漂白丝、毛织物,可用3%浓度的双氧水,液量为织物重量的10倍,另加少许氨水使其带弱碱性,在一般室温下浸漂5-10小时后,洗净晾干。 ◆ 加柠檬汁法:洗白色丝织物时,在水里加点柠檬汁,可使衣物更加洁白。 ◆ 脱脂牛奶浸泡法:在洗白色丝织物前用脱脂牛奶泡一下,或最后一次漂洗时在水里加2汤匙牛奶,可保持白色丝织物的本色,防止其变黄。 ◆ 萝卜汤洗涤法:白衣物如污垢较多,可用萝卜汤来洗,可洁白如新。 ◆ 橘皮水浸泡法:洗涤白色衣物时,可将橘皮放入锅里加热烧沸,用那黄色汤水浸泡、搓洗衣服,便可使衣物洁白如新。 巧洗白色衣物 为了使白衬衫更洁白,在洗涤时,可在泡好的洗衣粉溶液中,加上漂白粉,浸泡20—30分钟以后再清洗。另外,经常用淘米水浸洗,白衬衣就不易发黄;或者衣服洗净后,再放入滴有蓝墨水的清水中漂洗,也能有效防止白衣发黄。 白背心穿久了在往发黄。使旧背心洁白如初的方法是:先用清水洗一洗,再用肥皂或洗衣粉揉搓,清水洗过后,用肥皂或洗衣粉轻轻搓出,不再漂洗,然后放入塑料袋里,扎好口,在日光下晒l小时以上,再搓洗出来。 洗白袜子时,只要在热水中放入2—3片柠檬,然后将洗后的白袜子浸泡10分钟,袜子便很容易洗净。 商场里有卖各种增白剂的不错, 单独洗涤,不要与其它衣物一起洗即使是颜色相似不退色的也不可 而且洗后用清水泡十五分钟,尽量不要让衣服上留有香皂、洗衣粉等的沫 放在阴凉的地方自已慢慢晒干,不要在烈日下晒 把洗后的衣服装进保鲜袋放进冰箱冷冻室,大约一个小时后取出,这也是别人推荐的方法,试试吧。还有就是用84试试。 主要是尽可能少晒太阳;洗衣服时单独洗;用好的中性清洗剂;适当用漂白剂。 另外有:1、反晒法。晾干衣服时,把衣服反过来,衣里朝阳,衣表背阴。 2、加剂法。人造纤维衣服洗涤时,要在水中加一些食盐;洗高级的衣料可以在水里加少量的明矾,这些都可以避免或减少衣服褪色。 3、酸洗法。洗涤有色布料衣服时,在洗涤剂中加1-2匙食醋,也能防止衣服褪色。
白衣服巧洗保洁白 ◆滴墨水法:在一盆干净的凉水中,滴3-5滴纯蓝墨水,用手搅匀,然后把洗漂干净的白衬衫放进水中,上下提拉3-5次,捞出晾干。 ◆加双氧水法:漂白丝、毛织物,可用3%浓度的双氧水,液量为织物重量的10倍,另加少许氨水使其带弱碱性,在一般室温下浸漂5-10小时后,洗净晾干。 ◆加柠檬汁法:洗白色丝织物时,在水里加点柠檬汁,可使衣物更加洁白。 ◆脱脂牛奶浸泡法:在洗白色丝织物前用脱脂牛奶泡一下,或最后一次漂洗时在水里加2汤匙牛奶,可保持白色丝织物的本色,防止其变黄。 ◆萝卜汤洗涤法:白衣物如污垢较多,可用萝卜汤来洗,可洁白如新。 ◆橘皮水浸泡法:洗涤白色衣物时,可将橘皮放入锅里加热烧沸,用那黄色汤水浸泡、搓洗衣服,便可使衣物洁白如新。 巧洗白色衣物 为了使白衬衫更洁白,在洗涤时,可在泡好的洗衣粉溶液中,加上漂白粉,浸泡20—30分钟以后再清洗。另外,经常用淘米水浸洗,白衬衣就不易发黄;或者衣服洗净后,再放入滴有蓝墨水的清水中漂洗,也能有效防止白衣发黄。 白背心穿久了在往发黄。使旧背心洁白如初的方法是:先用清水洗一洗,再用肥皂或洗衣粉揉搓,清水洗过后,用肥皂或洗衣粉轻轻搓出,不再漂洗,然后放入塑料袋里,扎好口,在日光下晒l小时以上,再搓洗出来。 洗白袜子时,只要在热水中放入2—3片柠檬,然后将洗后的白袜子浸泡10分钟,袜子便很容易洗净。 商场里有卖各种增白剂的不错, 单独洗涤,不要与其它衣物一起洗即使是颜色相似不退色的也不可 而且洗后用清水泡十五分钟,尽量不要让衣服上留有香皂、洗衣粉等的沫 放在阴凉的地方自已慢慢晒干,不要在烈日下晒 把洗后的衣服装进保鲜袋放进冰箱冷冻室,大约一个小时后取出,这也是别人推荐的方法,试试吧。还有就是用84试试。 主要是尽可能少晒太阳;洗衣服时单独洗;用好的中性清洗剂;适当用漂白剂。 1、反晒法。晾干衣服时,把衣服反过来,衣里朝阳,衣表背阴。 2、加剂法。人造纤维衣服洗涤时,要在水中加一些食盐;洗高级的衣料可以在水里加少量的明矾,这些都可以避免或减少衣服褪色。 3、酸洗法。洗涤有色布料衣服时,在洗涤剂中加1-2匙食醋,也能防止衣服褪色。 84消毒液能帮你解决。 按照瓶子上的使用方法进行浸泡后,白色的衣服会被漂的很白。 但如有其他颜色,就不行了,84消毒液会让其他颜色掉色的。 根据我的经验,白色衣服最好用洗衣粉洗涤,不要用肥皂或洗衣皂。 白衣服穿久了常会发黄,如果把它浸泡在加有蓝靛的溶液里漂洗,就可使其洁 白如新。或者84消毒液漂白 1.用一下陈醋来洗一下被染的地方 2.试试叫彩漂的化学用品,如白猫漂彩 3.用84消毒液稀释以后,稍微泡一下试试,不过一定要掌握好稀释的比例和浸泡的时间,这个和被染的衣服之地和被染程度有关系,最好多漂几次,宁可麻烦点,也不要漂过头了。 4.用安利洗 5.高锰酸钾和醋酸,做法是先将少许高锰酸钾溶于水,再将要漂洗的衣服放进去,要充分浸透,浸10至20分钟后,衣服会呈暗红色,将衣服拿起,洗一下清水;再将少许醋酸溶于水,把浸过高锰酸钾的衣服放入醋酸溶液中,衣服就会由暗红色慢慢转变为原来的颜色,并且染了色的地方也一并褪掉而不会损坏衣服原有的颜色.有时穿到发黄的衣服也可以用这个办法. 6.用含阴离子表面活性剂多的洗衣粉和洗洁精1:1加入温水中,把被染的地方放入温水中浸泡半个小时以上,再用手去搓洗。如果还是去不干净,就把全部的衣服都放进50度以上水中,加入少量的洗衣粉搓洗,利用该衣服的褪色来减小被染色的色差。 7.被染色的地方画成,或者绣上一朵花,一花遮百丑!哈哈^-^ 8.将被染色处用水打湿.再将食用盐涂满.再用手反复轻搓.被染之色便没了.再用清水清洗即可. 9.把染了色的衣物放入盛有热水的盆中,每升水加10匙小苏打。用月桂树叶覆盖衣物,就这样放一夜,次日早上,清洗一下,你会发现它们又重现白. 注意:漂白漂出的衣服对身体不好,漂白是利用化学药品特殊锡化合物,是很强的氯制品,掌握不好衣服就会烧坏。有的是用高锰酸钾,再经双氧水强氧化漂白的,如果不白有的还加荧光增白剂。这些对人体都非常不利的.
在洗衣机里放入温水,启动洗衣机进行漂洗,加入84消毒液,半缸水加大约三分之一瓶消毒液,溶解稀释,放入衣服,盖上机盖,漂洗大约25分钟, 25分钟后捞出衣物,衣服晾干后,就回复原来的颜色了。 如果想避免衣服不掉色,刚买回来的新衣衣,必须在水里放些盐(一桶水一小匙),洗后要马上用清水漂洗干净,不要泡太久哦!最后,不要在阳光下曝晒,阳光会使染料变性的哦~~应放在阴凉通风处晾干:) 1.用一下陈醋来洗一下被染的地方 2.试试叫彩漂的化学用品,如白猫漂彩 3.用84消毒液稀释以后,稍微泡一下试试,不过一定要掌握好稀释的比例和浸泡的时间,这个和被染的衣服之地和被染程度有关系,最好多漂几次,宁可麻烦点,也不要漂过头了。 4.用安利洗 5.高锰酸钾和醋酸,做法是先将少许高锰酸钾溶于水,再将要漂洗的衣服放进去,要充分浸透,浸10至20分钟后,衣服会呈暗红色,将衣服拿起,洗一下清水;再将少许醋酸溶于水,把浸过高锰酸钾的衣服放入醋酸溶液中,衣服就会由暗红色慢慢转变为原来的颜色,并且染了色的地方也一并褪掉而不会损坏衣服原有的颜色.有时穿到发黄的衣服也可以用这个办法. 6.用含阴离子表面活性剂多的洗衣粉和洗洁精1:1加入温水中,把被染的地方放入温水中浸泡半个小时以上,再用手去搓洗。如果还是去不干净,就把全部的衣服都放进50度以上水中,加入少量的洗衣粉搓洗,利用该衣服的褪色来减小被染色的色差。 7.被染色的地方画成,或者绣上一朵花,一花遮百丑!哈哈^-^ 8.将被染色处用水打湿.再将食用盐涂满.再用手反复轻搓.被染之色便没了.再用清水清洗即可. 9.把染了色的衣物放入盛有热水的盆中,每升水加10匙小苏打。用月桂树叶覆盖衣物,就这样放一夜,次日早上,清洗一下,你会发现它们又重现白. 注意:漂白漂出的衣服对身体不好,漂白是利用化学药品特殊锡化合物,是很强的氯制品,掌握不好衣服就会烧坏。有的是用高锰酸钾,再经双氧水强氧化漂白的,如果不白有的还加荧光增白剂。这些对人体都非常不利的. 这些是我在网上找的好东东,记得上次我最爱的一件白色T恤被染色了,我就试了1、3、8综合的方法:用消毒液(即:消洗灵)稀释后,倒入几点白醋,将衣服染色部位浸泡5-10分钟(具体时间没看,估计的)。后来居然一点颜色都没有了。各位如果衣服被染色了,试试上面几种方法吧!!!千万不能与深色衣服及会掉色的衣服一起洗
衣服恢复白色小窍门
夏天的白背心或短袖,经过一夏天汉水的浸泡和日晒,早已失去原色,变得发黄,不亮丽。用什么方法使它恢复白色。
现在盆里接入一些凉水,不要太多,只...
不能和洗衣粉一道洗,因为84消毒液属酸性,洗衣粉属碱性,两者中和不但洗不了衣,还而使衣服严重变色,使你的白衣服白不白,灰不灰的。用84消毒液浸泡白衣服,浓度不能...
1)泛黄衣服的拯救策略
衣服会变黄,多半是荧光剂变弱所致,想要衣物恢复洁白亮丽,就得想法子。
洗米水+橘子皮简单又有效:
保留洗米水或是将橘子皮放入锅内加水烧煮...
我告诉你个好的办法。我以前有一件NIKE白色外套,不小心把墨水弄的满袖子都是。我是一个任教于兰州大学的应用化学的老师。你直接取个水桶在桶内加一2/3的温水,在向...
洗的时候可以加一点漂白水,一瓶盖就行,但要有三点需要注意:
1、一定不要在太阳下暴晒
2、晾衣服之前必须要漂洗干净,多投几遍。
3、爱沾上汗渍的地方,比如领口和...
答: 是诈骗吗
答: 这么年轻就感觉活得累了 ,你也太低估自己的潜在的能力了。应该振作起来,增强自信心,努力奋斗,使自己能够生活幸福!
人活着就是为了生活更快乐,更幸福,而幸福的生活...
答: 五款失眠食疗方
中医认为失眠主要是由于脏腑阴阳失调,气血不和引起的。因此,对失眠患者应着重调治脏腑及气血阴阳,如补益心肺、滋阴降火、疏肝养血、益气镇惊、化痰清热...
大家还关注
Copyright &
Corporation, All Rights Reserved
确定举报此问题
举报原因(必选):
广告或垃圾信息
激进时政或意识形态话题
不雅词句或人身攻击
侵犯他人隐私
其它违法和不良信息
报告,这不是个问题
报告原因(必选):
这不是个问题
这个问题分类似乎错了
这个不是我熟悉的地区Hackbuteer1的专栏Stay Hungry,Stay Foolish!
Hackbuteer1的专栏Stay Hungry,Stay Foolish!
转自:http://blog.csdn.net/Hackbuteer1/rss/list
[原]九度互动社区IT名企招聘上机考试热身赛
http://ac.jobdu.com/problem.php?id=1326
Waiting in Line
//简单模拟题
#include&i...
阅读:227 评论:0
一、 什么是单调(双端)队列
单调队列,顾名思义,就是一个元素单调的队列,那么就能保证队首的元素是最小(最大)的,从而满足动态规划的最优性问题的需求。
单调队列,又名双端队列。双端队列,就是说它不同于一般的队列只能在队首删除、队尾插入,它能够在队首、队尾同时进行删除。
【单调队列的性质】
一般,在动态规划的过程中,单调队列中每个元素一般存储的是两个值:
1、在原数列中的位置(下标)
2、 他在动态规划中的状态值
而单调队列则保证这两个值同时单调。
从以上看,单调队列的元素最好用一个类来放,不这样的话,就要开两个数组。。。
单调队列:单调队列 即保持队列中的元素单调递增(或递减)的这样一个队列,可以从两头删除,只能从队尾插入。单调队列的具体作用在于,由于保持队列中的元素满足单调性,对手元素便是极小值(极大值)了。
//poj-2823--单调队列
#include&iostream&
#include&cstdio&
const int MAX = 1000001;
//两个单调队列
int dq1[MAX];
//一个存单调递增
int dq2[MAX];
//一个存单调递减
int a[MAX];
inline bool scan_d(int &num)
这个就是 加速的 关键了
in=getchar();
if(in==EOF)
while(in!='-'&&(in&'0'||in&'9')) in=getchar();
if(in=='-')
{ IsN=num=0;}
else num=in-'0';
while(in=getchar(),in&='0'&&in&='9')
num*=10,num+=in-'0';
int main(void)
int i,n,k,front1,front2,tail1,tail2,start,
while(scanf("%d %d",&n,&k)!=EOF)
for(i = 0 ; i & ++i)
scan_d(a[i]);
front1 = 0, tail1 = -1;
front2 = 0, tail2 = -1;
ans = start = 0;
for(i = 0 ; i & ++i)
while(front1 &= tail1 && a[ dq1[tail1] ] &= a[i])
//当前元素大于单调递增队列的队尾元素的时候,队尾的元素依次弹出队列,直到队尾元素大于当前当前元素的时候,将当前元素插入队尾
dq1[ ++tail1 ] =
//只需要记录下标即可
while(front2 &= tail2 && a[ dq2[tail2] ] &= a[i])
//当前元素小于单调递减队列的队尾元素的时候,队尾的元素依次弹出队列,直到队尾元素小于当前当前元素的时候,将当前元素插入队尾
dq2[ ++tail2 ] =
//只需要记录下标即可
printf("%d ",a[ dq2[ front2 ] ]);
for( ; i & ++i)
while(front2 &= tail2 && a[ dq2[tail2] ] &= a[i])
dq2[ ++tail2 ] =
while(dq2[ front2 ] &= i - k)
if(i != n-1)
printf("%d ",a[ dq2[ front2 ] ]);
printf("%d\n",a[ dq2[ front2 ] ]);
//输出最大值
printf("%d ",a[ dq1[ front1 ] ]);
for(i= i & ++i)
while(front1 &= tail1 && a[ dq1[tail1] ] &= a[i])
dq1[ ++tail1 ] =
while(dq1[ front1 ] &= i - k)
if(i != n-1)
printf("%d ",a[ dq1[ front1 ] ]);
printf("%d\n",a[ dq1[ front1 ] ]);
Subsequence
题意:给出一个序列,求最长的连续子序列,使得 M&=Max-Min&=K
依次枚举剩下的N-1个元素,并且将当前未入队的第一个元素和队尾元素比较,当且仅当队列为非空并且队尾元素的值小于当前未入队的元素时,
将队尾元素删除(也就是队尾指针-1),因为当前的元素比队尾元素大,所以在区间内队尾元素不会是最大值了。
重复这个过程直到队列空或者队尾元素比当前元素大,
#include&iostream&
#include&cstdio&
const int MAX = 100001;
//两个单调队列
int dq1[MAX];
//一个存单调递增
int dq2[MAX];
//一个存单调递减
int a[MAX];
inline bool scan_d(int &num)
这个就是 加速的 关键了
in=getchar();
if(in==EOF)
while(in!='-'&&(in&'0'||in&'9')) in=getchar();
if(in=='-')
{ IsN=num=0;}
else num=in-'0';
while(in=getchar(),in&='0'&&in&='9')
num*=10,num+=in-'0';
int main(void)
int i,n,m,k,front1,front2,tail1,tail2,start,
while(scanf("%d %d %d",&n,&m,&k) != EOF)
for(i = 0 ; i & ++i)
scan_d(a[i]);
front1 = 0, tail1 = -1;
front2 = 0, tail2 = -1;
ans = start = 0;
for(i = 0 ; i & ++i)
while(front1 &= tail1 && a[ dq1[tail1] ] &= a[i])
//当前元素大于单调递增队列的队尾元素的时候,队尾的元素依次弹出队列,直到队尾元素大于当前当前元素的时候,将当前元素插入队尾
dq1[ ++tail1 ] =
//只需要记录下标即可
while(front2 &= tail2 && a[ dq2[tail2] ] &= a[i])
//当前元素小于单调递减队列的队尾元素的时候,队尾的元素依次弹出队列,直到队尾元素小于当前当前元素的时候,将当前元素插入队尾
dq2[ ++tail2 ] =
//只需要记录下标即可
Max - Min 为两个队列的队首之差
while(Max-Min&K)
看哪个的队首元素比较靠前,就把谁往后移动
while(a[ dq1[front1] ] - a[ dq2[front2] ] & k)
if(dq1[front1] & dq2[front2] )
start = dq1[front1] + 1;
start = dq2[front2] + 1;
if(a[ dq1[front1] ] - a[ dq2[front2] ] &= m)
if(i - start +1 & ans)
ans = i - start + 1;
printf("%d\n",ans);
作者:Hackbuteer1 发表于 21:54:38
阅读:223 评论:0
1、计算表达式x6+4x4+2x3+x+1最少需要做()次乘法
第一次乘法:x^2,第二次乘法:x^4=x^2 * x^2,第三次乘法:原式=x^2 * (x^4+4x^2+2x)+x+1,每一项的系数可以使用加法来实现。。
2、给定3个int类型的正整数x,y,z,对如下4组表达式判断正确的选项()
Int a1=x+y-z; int b1=x*y/z;
Int a2=x-z+y; int b2=x/z*y;
Int c1=x&&y&&z; int d1=x&y|z;
Int c2=x&&z&&y; int d2=x|z&y;
A、a1一定等于a2
B、b1一定定于b2
C、c1一定等于c2
D、d1一定等于d2
3、程序的完整编译过程分为是:预处理,编译,汇编等,如下关于编译阶段的编译优化的说法中不正确的是()
A、死代码删除指的是编译过程直接抛弃掉被注释的代码;
B、函数内联可以避免函数调用中压栈和退栈的开销
C、For循环的循环控制变量通常很适合调度到寄存器访问
D、强度削弱是指执行时间较短的指令等价的替代执行时间较长的指令
4、 如下关于进程的描述不正确的是()
A、进程在退出时会自动关闭自己打开的所有文件
B、进程在退出时会自动关闭自己打开的网络链接
C、进程在退出时会自动销毁自己创建的所有线程
D、进程在退出时会自动销毁自己打开的共享内存
5、 在如下8*6的矩阵中,请计算从A移动到B一共有多少种走法?要求每次只能向上挥着向右移动一格,并且不能经过P;
6、SQL语言中删除一个表的指令是()
A、DROP TABLE
B、DELETE TABLE
C、DESTROY TABLE
D、REMOVE TABLE
7、某产品团队由美术组、产品组、client程序组和server程序组4个小组构成,每次构建一套完整的版本时,需要各个组发布如下资源。美术组想客户端提供图像资源(需要10分钟),产品组向client组合server提供文字内容资源(同时进行,10分钟),server和client源代码放置在不同工作站上,其完整编译时间均为10分钟切编译过程不依赖于任何资源,client程序(不包含任何资源)在编译完毕后还需要完成对程序的统一加密过程(10分钟)。可以请问,从要完成一次版本构建(client与server的版本代码与资源齐备),至少需要多少时间()
8、如下关于编译链接的说法错误的是()
A、编译优化会使得编译速度变慢
B、预编译头文件可以优化程序的性能
C、静态链接会使得可执行文件偏大
D、动态链接库会使进程启动速度偏慢
9、如下关于链接的说法错误的是()
A、一个静态库中不能包含两个同名全局函数的定义
B、一个动态库中不能包含两个同名全局函数的定义
C、如果两个静态库都包含一个同名全局函数,他们不能同时被链接
D、如果两个动态库都包含一个同名全局函数,他们不能同时被链接
10、排序算法的稳定是指,关键码相同的记录排序前后相对位置不发生改变,下面哪种排序算法是不稳定的()
A、插入排序
B、冒泡排序
C、快速排序
D、归并排序
11、下列说法中错误的是:()
A、插入排序某些情况下复杂度为O(n)
B、排序二叉树元素查找的复杂度可能为O(n)
C、对于有序列表的排序最快的是快速排序
D、在有序列表中通过二分查找的复杂度一定是O(n log2n)
12、在程序设计中,要对两个16K×16K的多精度浮点数二维数组进行矩阵求和时,行优先读取和列优先读取的区别是()
B、行优先快
C、列优先快
D、2种读取方式速度为随机值,无法判断
13、字符串所有非空子串(两个子串如果内容相同则只算一个)个数是()
14、TCP的关闭过程,说法正确的是()
A、TIME_WAIT状态称为MSL(Maximum Segment Lifetime)等待状态
B、对一个established状态的TCP连接,在调用shutdown函数之前调用close接口,可以让主动调用的一方进入半关闭状态
C、主动发送FIN消息的连接端,收到对方回应ack之前不能发只能收,在收到对方回复ack之后不能发也不能收,进入CLOSING状态
D、在已经成功建立连接的TCP连接上,如果一端收到RST消息可以让TCP的连洁端绕过半关闭状态并允许丢失数据。
15、操作系统的一些特别端口要为特定的服务做预留,必须要root权限才能打开的端口描述正确的是()
A、端口号在之间的端口
B、所有小于1024的每个端口
C、RFC标准文档中已经声明特定服务的相关端口,例如http服务的80端口,8080端口等
D、所有端口都可以不受权限限制打开
16、图书馆有6人排队,其中3人要还同一本书,书名为《面试宝典》,另外3人要借。问求能保证另外3人借到的种类。Catalan数 C(2n , n)/( n+1 )
C(6,3)/4 = 5
5*3!*3! = 180
17、ack(3 , 3)的执行结果是多少?
int ack(int m,int n)
if(m == 0)
return n + 1;
else if(n == 0)
return ack(m-1,1);
return ack(m - 1 , ack(m , n-1));
这个题目可以找规律的。。
18、如下SQL语句是需要列出一个论坛版面第一页(每页显示20个)的帖子(post)标题(title),并按照发布(create_time)降序排列:
SELECT title FROM post( )create_time DESC( )0,20
19、为了某项目需要,我们准备构造了一种面向对象的脚本语言,例如,对所有的整数,我们都通过Integer类型的对象来描述。在计算“1+2”时,这里的“1”,“2”和结果“3”分别为一个Integer对象。为了降低设计复杂度,我们决定让Integer对象都是只读对象,也即在计算a=a+b后,对象a引用的是一个新的对象,而非改a所指对象的值。考虑到性能问题,我们又引入两种优化方案:(1)对于数值相等的Integer对象,我们不会重复创建。例如,计算“1+1”,这里两个“1”的引用的是同一个对象——这种设计模式叫做();(2)脚本语言解析器启动时,默认创建数值范围[1,32]的32个Integer对象。现在,假设我们要计算表达式“1+2+3+…+40”,在计算过程需要创建的Integer对象个数是()。
享元模式20、甲、乙两个人在玩猜数字游戏,甲随机写了一个数字,在[1,100]区间之内,将这个数字写在了一张纸上,然后乙来猜。
如果乙猜的数字偏小的话,甲会提示:“数字偏小”
一旦乙猜的数字偏大的话,甲以后就再也不会提示了,只会回答“猜对 或 猜错”
问: 乙至少猜
猜可以准确猜出这个数字,在这种策略下,
乙猜的第一个数字是多少???
答案:猜测序列是14,、27、39、50、60、69、77、84、90、95、99
因为无论第几次猜大了,最终的总次数总是14。
这个题目类似于一道Google面试题 :
扔玻璃球求最高楼层。。
一道关于动态规划的面试题——Google面试题:扔玻璃珠某幢大楼有100层。你手里有两颗一模一样的玻璃珠。当你拿着玻璃珠在某一层往下扔的时候,一定会有两个结果,玻璃珠碎了或者没碎。这幢大楼有个临界楼层。低于它的楼层,往下扔玻璃珠,玻璃珠不会碎,等于或高于它的楼层,扔下玻璃珠,玻璃珠一定会碎。玻璃珠碎了就不能再扔。现在让你设计一种方式,使得在该方式下,最坏的情况扔的次数比其他任何方式最坏的次数都少。也就是设计一种最有效的方式。首先,为了保存下一颗玻璃珠自己玩,就采用最笨的办法吧:从第一层开始试,每次增加一层,当哪一层扔下玻璃珠后碎掉了,也就知道了。不过最坏的情况扔的次数可能为100。当然,为了这一颗玻璃珠代价也高了点,还是采取另外一种办法吧。随便挑一层,假如为N层,扔下去后,如果碎了,那就只能从第一层开始试了,最坏的情况可能为N。假如没碎,就一次增加一层继续扔吧,这时最坏的情况为100-N。也就是说,采用这种办法,最坏的情况为max{N, 100-N+1}。之所以要加一,是因为第一次是从第N层开始扔。不过还是觉得不够好,运气好的话,挑到的N可能刚好是临界楼层,运气不好的话,要扔的次数还是很多。不过回过头看看第二种方式,有没有什么发现。假如没摔的话,不如不要一次增加一层继续扔吧,而是采取另外一种方式:把问题转换为100-N,在这里面找临界楼层,这样不就把问题转换成用递归的方式来解决吗?看下面:假如结果都保存在F[101]这个数组里面,那么:F[N]=100-N,F[100]=min(max(1,1+F[N-1]),max(2,1+F[N-2]),……,max(N-1,1+F[1]));看出来了没有,其实最终就是利用动态规划来解决这个问题。下面是自己随便写的C++代码:
#include&iostream&
int dp[101] = { 0 };
void solve()
int i , j ,
for(i = 2 ; i & 101 ; ++i)
for(j = 1 ; j & ++j)
k = (j&=(1 + dp[i-j])) ? j : (1 + dp[i-j]);
if(dp[i] & k)
int main(void)
dp[0] = 0 , dp[1] = 1;
printf("%d\n",dp[100]);
}输出结果为14。也就是说,最好的方式只要试14次就能够得出结果了。
答案是先从14楼开始抛第一次;如果没碎,再从27楼抛第二次;如果还没碎,再从39楼抛第三次;如果还没碎,再从50楼抛第四次;如此,每次间隔的楼层少一层。这样,任何一次抛棋子碎时,都能确保最多抛14次可以找出临界楼层。
证明如下:
1、第一次抛棋子的楼层:最优的选择必然是间隔最大的楼层。比如,第一次如果在m层抛下棋子,以后再抛棋子时两次楼层的间隔必然不大于m层(大家可以自己用反证法简单证明)
2、从第二次抛棋子的间隔楼层最优的选择必然比第一次间隔少一层,第三次的楼层间隔比第二次间隔少一层,如此,以后每次抛棋子楼层间隔比上一次间隔少一层。(大家不妨自己证明一下)
3、所以,设n是第一次抛棋子的最佳楼层,则n即为满足下列不等式的最小自然数:
不等式如下:
1+2+3+...+(n-1)+n
由上式可得出n=14
即最优的策略是先从第14层抛下,最多抛14次肯定能找出临界楼层。
21、给定一个数组a[N],我们希望构造数组b[N],其中b[i]=a[0]*a[1]*...*a[N-1]/a[i]。在构造过程:
不允许使用除法;
要求O(1)空间复杂度和O(n)时间复杂度;
除遍历计数器与a[N] b[N]外,不可使用新的变量(包括栈临时变量、对空间和全局静态变量等);
请用程序实现并简单描述。
思路:进行3趟扫描
第一趟从左到右对A进行累乘,结果保存在B数组中,b[i] = b[i-1]*a[i-1];
第二趟从右到左对A进行累乘,结果写入A中,a[i]=a[i+1]*a[i];
第三趟从左到右,然后B数组对应位置的元素等于其前一个位置的元素与A中其后一个位置的元素的乘积。b[i] = a[i+1] * b[i-1]
void makeArray(int a[],int b[],int len)
for(i = 1 ; i & ++i)
b[i] = b[i-1] * a[i-1];
// b[0] = 1 , b[i] = a[0]*a[1]*...*a[i-1]
a[len - 1] = a[len - 1]^a[len - 2];
//不使用中间变量,通过位运算来交换两个变量
a[len - 2] = a[len - 1]^a[len - 2];
a[len - 1] = a[len - 1]^a[len - 2];
for(i = len - 3 ; i &= 0 ; --i)
a[len - 1] = a[i + 1] * a[len - 1];
a[i] = a[i]^a[len - 1];
//交换两个变量
a[len - 1] = a[i]^a[len - 1];
a[i] = a[i]^a[len - 1];
a[len - 1 ] = 1;
//a[len - 1 ] = 1 , a[i] = a[i+1]*a[i+2]*...*a[len-1]
for(i = 0 ; i & ++i)
b[i] = a[i] * b[i];
//方法二,保持a数组不变
void makeArray(int a[],int b[],int len)
for(i = 1 ; i & ++i)
b[0] *= a[i-1];
b[i] = b[0];
// b[i] = a[0]*a[1]*...*a[i-1]
for(i = len - 2 ; i & 0 ; --i)
b[0] *= a[i+1];
// b[0] = a[i+1]*a[i+2]...*a[len-1]
b[i] *= b[0];
// b[i] = a[0]*a[1]*...*a[i-1]*a[i+1]*...*a[len-1]
b[0] *= a[1];
void makeArray(int a[],int b[],int len)
for(i = 1 ; i & ++i)
b[i] = b[i-1] * a[i-1];
// b[i] = a[0]*a[1]*...*a[i-1]
b[0] = a[len - 1];
for(i = len - 2 ; i & 0 ; --i)
b[i] *= b[0];
// b[i] = a[0]*a[1]*...*a[i-1]*a[i+1]*...*a[len-1]
b[0] *= a[i];
// b[0] = a[i+1]*a[i+2]...*a[len-1]
}22、20世纪60年代,美国心理学家米尔格兰姆设计了一个连锁信件实验。米尔格兰姆把信随即发送给住在美国各城市的一部分居民,信中写有一个波士顿股票经纪人的名字,并要求每名收信人把这封信寄给自己认为是比较接近这名股票经纪人的朋友。这位朋友收到信后再把信寄给他认为更接近这名股票经纪人的朋友。最终,大部分信件都寄到了这名股票经纪人手中,每封信平均经受6.2词到达。于是,米尔格兰姆提出六度分割理论,认为世界上任意两个人之间建立联系最多只需要6个人。
假设QQ号大概有10亿个注册用户,存储在一千台机器上的关系数据库中,每台机器存储一百万个用户及其的好友信息,假设用户的平均好友个数大约为25人左右。
第一问:请你设计一个方案,尽可能快的计算存储任意两个QQ号之间是否六度(好友是1度)可达,并得出这两位用户六度可达的话,最短是几度可达。
第二问:我们希望得到平均每个用户的n度好友个数,以增加对用户更多的了解,现在如果每台机器一秒钟可以返回一千条查询结果,那么在10天的时间内,利用给出的硬件条件,可以统计出用户的最多几度好友个数?如果希望得到更高的平均n度好友个数,可以怎样改进方案?
23、段页式虚拟存储管理方案的特点。
答:空间浪费小、存储共享容易、存储保护容易、能动态连接。
段页式管理是段式管理和页式管理结合而成,兼有段式和页式管理的优点,每一段分成若干页,再按页式管理,页间不要求连续(能动态连接);用分段方法分配管理作业,用分页方法分配管理内存(空间浪费小)。
段页式管理采用二维地址空间,如段号(S)、页号(P)和页内单元号(D);系统建两张表格每一作业一张段表,每一段建立一张页表,段表指出该段的页表在内存中的位置;地址变换机构类似页式机制,只是前面增加一项段号。所以存储共享容易、存储保护容易。
作者:Hackbuteer1 发表于 22:35:48
阅读:1674 评论:21
1、已知两个数字为1~30之间的数字,甲知道两数之和,乙知道两数之积,甲问乙:“你知道是哪两个数吗?”乙说:“不知道”。乙问甲:“你知道是哪两个数吗?”甲说:“也不知道”。于是,乙说:“那我知道了”,随后甲也说:“那我也知道了”,这两个数是什么?
答:1和4 或者1和7
2、一个环形公路,上面有N个站点,A1, ..., AN,其中Ai和Ai+1之间的距离为Di,AN和A1之间的距离为D0。
高效的求第i和第j个站点之间的距离,空间复杂度不超过O(N)
它给出了部分代码如下:
#define N 25
double D[N]
void Preprocess()
//Write your code1;
double Distance(int i, int j)
//Write your code2;
const int N = 10;
int A1toX[N];
void Preprocess()
srand(time(0));
for (int i = 0; i & N; ++i)
D[i] = (rand()/(RAND_MAX+1.0)) * N;
A1toX[1] = D[1];
//from A1 to A2
for (int i = 2; i & N; ++i)
A1toX[i] = A1toX[i-1] + D[i];
//distance from A1 to each point
A1toX[0] = A1toX[N-1] + D[0];
// total length
int distance(int i, int j)
int di = (i == 0) ? 0 : A1toX[i-1];
int dj = (j ==0) ? 0 : A1toX[j-1];
int dist = abs(di - dj);
return dist & A1toX[0]/2 ? A1toX[0] - dist :
int main(void)
Preprocess();
for (int i = 0; i &N; ++i)
cout&&D[i]&&" ";
for (int i = 1; i &= N; ++i)
cout&&"distance from A1 to A"&&i&&": "&&distance(1, i)&&
3、 一个字符串,压缩其中的连续空格为1个后,对其中的每个字串逆序打印出来。比如"abc
hij"打印为"cba gfe jih"。
#include&iostream&
#include&cstdio&
#include&stack&
#include&string&
string reverse(string str)
stack&char&
int len = str.length();
string ret = "";
for (int p = 0, q = 0;p &)
if (str[p] == ' ')
ret.append(1,' ');
for (q = q & len && str[q] == ' '; q++)
for (q = q & len && str[q] != ' '; q++)
stk.push(str[q]);
while(!stk.empty())
ret.append(1,stk.top());
stk.pop();
int main(void)
string s = "abc def
cout&&reverse(s).c_str()&&
} 4、将一个较大的钱,不超过^6)的人民币,兑换成数量不限的100、50、10、5、2、1的组合,请问共有多少种组合呢?(完全背包)(其它选择题考的是有关:操作系统、树、概率题、最大生成树有关的题,另外听老梦说,谷歌不给人霸笔的机会。)。
作者:Hackbuteer1 发表于 21:21:26
阅读:415 评论:0
1、Suppose that a selection sort of 80 items has completed 32 iterations of the main loop. How many items are now guaranteed to be in their final spot (never to be moved again)?
2、Which synchronization mechanism(s) is/are used to avoid race conditions among processes/threads in operating system?A、Mutex
B、Mailbox
C、Semaphore
D、Local procedure call
3、There is a sequence of n numbers 1,2,3,...,n and a stack which can keep m numbers at most. Push the n numbers into the stack following the sequence and pop out randomly . Suppose n is 2 and m is 3,the output sequence may be 1,2 or 2,1,so we get 2 different sequences . Suppose n is 7,and m is 5,please choose the output sequence of the stack.A、1,2,3,4,5,6,7B、7,6,5,4,3,2,1C、5,6,4,3,7,2,1D、1,7,6,5,4,3,2
E、3,2,1,7,5,6,4
4、Which is the result of binary number
after multiplying by 0111001 and adding 1101110?A、1111
B、0011C、0101
转化为10进制操作以后,再转化为二进制就可以了。
5、What is output if you compile and execute the following c code?
void main()
int i = 11;
int const *p = &i;
printf("%d",*p);
B、12C、Garbage value
D、Compile error
E、None of above6、Which of following C++ code is correct ?
int *a = new int(3);
return *a;
}B、int *f()
int a[3] = {1,2,3};
}C、vector&int& f()
vector&int& v(3);
}D、void f(int *ret)
int a[3] = {1,2,3};
E、None of above
7、Given that the 180-degree rotated image of a 5-digit number is another 5-digit number and the difference between the numbers is 78633, what is the original 5-digit number?
8、Which of the following statements are trueA、We can create a binary tree from given inorder and preorder traversal sequences.
B、We can create a binary tree from given preorder and postorder traversal sequences.C、For an almost sorted array,Insertion sort can be more effective than Quciksort.
D、Suppose T(n) is the runtime of resolving a problem with n elements, T(n)=O(1) if n=1;
T(n)=2*T(n/2)+O(n) if n&1; so T(n) is O(nlgn)
E、None of above
9、Which of the following statements are true?
A、Insertion sort and bubble sort are not efficient for large data sets.B、Qucik sort makes O(n^2) comparisons in the worst case.
C、There is an array :7,6,5,4,3,2,1. If using selection sort (ascending),the number of swap operations is 6D、Heap sort uses two heap operations:insertion and root deletion (插入、堆调整)
E、None of above
10、Assume both x and y are integers,which one of the followings returns the minimum of the two integers?A、y^((x^y) & -(x&y))
B、y^(x^y)
C、x^(x^y)
D、(x^y)^(y^x)E、None of above
x&y的时候,-(x&y)即-1的补码形式就是全1(111111),(x^y)&-(x&y)== x^y。x&y的时候,-(x&y)即0的补码形式就是全0(000000),(x^y)&-(x&y)== 0
11、The Orchid Pavilion(兰亭集序) is well known as the top of “行书”in history of Chinese literature. The most fascinating sentence is "Well I know it is a lie to say that life and death is the same thing, and that longevity and early death make no difference Alas!"(固知一死生为虚诞,齐彭殇为妄作).By counting the characters of the whole content (in Chinese version),the result should be 391(including punctuation). For these characters written to a text file,please select the possible file size without any data corrupt.
A、782 bytes in UTF-16 encoding
B、784 bytes in UTF-16 encoding
C、1173 bytes in UTF-8 encodingD、1176 bytes in UTF-8 encoding
E、None of above
12、Fill the blanks inside class definition
class Test
Test::Test(int _a , int _b) : a( _a )
int Test::b;
int main(void)
Test t1(0 , 0) , t2(1 , 1);
t1.b = 10;
t2.b = 20;
printf("%u %u %u %u",t1.a , t1.b , t2.a , t2.b);
} Running result : 0
A、static/const
B、const/static
C、--/static
D、conststatic/static
E、None of above
13、A 3-order B-tree has 2047 key words,what is the maximum height of the tree?
14、In C++,which of the following keyword(s)can be used on both a variable and a function?A、static
B、virtual
15、What is the result of the following program?char *f(char *str , char ch)
char *it1 =
char *it2 =
while(*it2 != '\0')
while(*it2 == ch)
*it1++ = *it2++;
int main(void)
char *a = new char[10];
strcpy(a , "abcdcccd");
cout&&f(a,'c');
}A、abdcccd
C、abccD、abddcccd
E、Access violation16、Consider the following definition of a recursive function,power,that will perform exponentiation.
int power(int b , int e)
if(e == 0)
if(e % 2 == 0)
return power(b*b , e/2);
return b * power(b*b , e/2);
}Asymptotically(渐进地) in terms of the exponent e,the number of calls to power that occur as a result of the call power(b,e) isA、logarithmic
C、quadratic
D、exponential
17、Assume a full deck of cards has 52 cards,2 blacks suits (spade and club) and 2 red suits(diamond and heart). If you are given a full deck,and a half deck(with 1 red suit and 1 black suit),what is the possibility for each one getting 2 red cards if taking 2 cards?
18、There is a stack and a sequence of n numbers(i.e. 1,2,3,...,n), Push the n numbers into the stack following the sequence and pop out randomly . How many different sequences of the n numbers we may get? Suppose n is 2 , the output sequence may 1,2 or 2,1, so wo get 2 different sequences .
A、C_2n^nB、C_2n^n - C_2n^(n+1)
C、((2n)!)/(n+1)n!n!
E、None of above
19、Longest Increasing Subsequence(LIS) means a sequence containing some elements in another sequence by the same order, and the values of elements keeps increasing.
For example, LIS of {2,1,4,2,3,7,4,6} is {1,2,3,4,6}, and its LIS length is 5.
Considering an array with N elements , what is the lowest time and space complexity to get the length of LIS?
A、Time : N^2 , Space : N^2
B、Time : N^2 , Space : NC、Time : NlogN , Space : N
D、Time : N , Space : N
E、Time : N , Space : C20、What is the output of the following piece of C++ code ?
#include&iostream&
struct Item
Item *Routine1(Item *x)
Item *prev = NULL,
while(curr)
Item *next = curr-&
curr-&next =
void Routine2(Item *x)
Item *curr =
while(curr)
cout&&curr-&c&&" ";
curr = curr-&
int main(void)
d = {'d' , NULL},
c = {'c' , &d},
b = {'b' , &c},
a = {'a' , &b};
x = Routine1( &a );
Routine2( x );
A、 c b a d
B、 b a d c
C、 d b c a
D、 a b c dE、 d c b a
作者:Hackbuteer1 发表于 22:20:22
阅读:1095 评论:13
Catalan数——卡特兰数
今天阿里淘宝笔试中碰到两道组合数学题,感觉非常亲切,但是笔试中失踪推导不出来
后来查了下,原来是Catalan数。悲剧啊,现在整理一下
一、Catalan数的定义令h(1)=1,Catalan数满足递归式:h(n) = h(1)*h(n-1) + h(2)*h(n-2) + ... + h(n-1)h(1),n&=2该递推关系的解为:h(n) = C(2n-2,n-1)/n,n=1,2,3,...(其中C(2n-2,n-1)表示2n-2个中取n-1个的组合数)
12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种?
这个笔试题,很YD,因为把某个递推关系隐藏得很深。
我们先把这12个人从低到高排列,然后,选择6个人排在第一排,那么剩下的6个肯定是在第二排.
用0表示对应的人在第一排,用1表示对应的人在第二排,那么含有6个0,6个1的序列,就对应一种方案.
比如就对应着
第一排:0 1 2 3 4 5
第二排:6 7 8 9 10 11
第一排:0 2 4 6 8 10
第二排:1 3 5 7 9 11
问题转换为,这样的满足条件的01序列有多少个。
观察1的出现,我们考虑这一个出现能不能放在第二排,显然,在这个1之前出现的那些0,1对应的人
要么是在这个1左边,要么是在这个1前面。而肯定要有一个0的,在这个1前面,统计在这个1之前的0和1的个数。
也就是要求,0的个数大于1的个数。
OK,问题已经解决。
如果把0看成入栈操作,1看成出栈操作,就是说给定6个元素,合法的入栈出栈序列有多少个。
这就是catalan数,这里只是用于栈,等价地描述还有,二叉树的枚举、多边形分成三角形的个数、圆括弧插入公式中的方法数,其通项是c(2n, n)/(n+1).
在&&计算机程序设计艺术&&,第三版,Donald E.Knuth著,苏运霖译,第一卷,508页,给出了证明:
问题大意是用S表示入栈,X表示出栈,那么合法的序列有多少个(S的个数为n)
显然有c(2n, n)个含S,X各n个的序列,剩下的是计算不允许的序列数(它包含正确个数的S和X,但是违背其它条件).
在任何不允许的序列中,定出使得X的个数超过S的个数的第一个X的位置。然后在导致并包括这个X的部分序列中,以S代替所有的X并以X代表所有的S。结果是一个有(n+1)个S和(n-1)个X的序列。反过来,对一垢一种类型的每个序列,我们都能逆转这个过程,而且找出导致它的前一种类型的不允许序列。例如XXSXSSSXXSSS必然来自SSXSXXXXXSSS。这个对应说明,不允许的序列的个数是c(2n, n-1),因此an = c(2n, n) - c(2n, n-1)。验证:其中F表示前排,B表示后排,在枚举出前排的人之后,对应的就是后排的人了,然后再验证是不是满足后面的比前面对应的人高的要求。
#include &iostream&
int bit_cnt(int n)
int result = 0;
for (; n &= n-1, ++result);
int main(void)
int F[6], B[6];
int i,j,k,state,ok,ans = 0;
for (state = 0; state & (1 && 12); ++state)
if (bit_cnt(state) == 6)
i = j = 0;
for (int k = 0; k & 12; ++k)
if(state&(1&&k))
for (k = 0; k & 6; ++k)
if (B[k] & F[k])
cout && ans &&
而c(12, 6)/7 = 12*11*10*9*8*7/(7*6*5*4*3*2) = 132
注意:c(2n, n)/(n+1) = c(2n, n) - c(2n, n-1)
估计出题的人也读过&&计算机程序艺术&&吧。
另一个很YD的问题:
有编号为1到n(n可以很大,不妨在这里假定可以达到10亿)的若干个格子,从左到右排列。
在某些格子中有一个棋子,不妨设第xi格有棋子(1&=i&=k, 1&=k&=n)
每次一个人可以把一个棋子往左移若干步,但是不能跨越其它棋子,也要保证每个格子至多只有一个棋子。
两个人轮流移动,移动不了的为输,问先手是不是有必胜策略。
三、Catalan数的典型应用:1、括号化问题。矩阵链乘: P=A1×A2×A3×……×An,依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,试问有几种括号化的方案?
一个有n个X和n个Y组成的字串,且所有的部分字串皆满足X的个数大于等于Y的个数。以下为长度为6的dyck words:
将上例的X换成左括号,Y换成右括号,Cn表示所有包含n组括号的合法运算式的个数:
2、将多边行划分为三角形问题。将一个凸多边形区域分成三角形区域(划分线不交叉)的方法数? 类似:在圆上选择2n个点,将这些点成对连接起来使得所得到的n条线段不相交的方法数?
3、出栈次序问题。一个栈(无穷大)的进栈序列为1、2、3、...、n,有多少个不同的出栈序列?
类似:有2n个人排成一行进入剧场。入场费5元。其中只有n个人有一张5元钞票,另外n人只有10元钞票,剧院无其它钞票,问有多少中方法使得只要有10元的人买票,售票处就有5元的钞票找零?(将持5元者到达视作将5元入栈,持10元者到达视作使栈中某5元出栈)类似:一位大城市的律师在他住所以北n个街区和以东n个街区处工作,每天她走2n个街区去上班。如果他从不穿越(但可以碰到)从家到办公室的对角线,那么有多少条可能的道路?
分析:对于每一个数来说,必须进栈一次、出栈一次。我们把进栈设为状态‘1’,出栈设为状态‘0’。n个数的所有状态对应n个1和n个0组成的2n位二进制数。由于等待入栈的操作数按照1‥n的顺序排列、入栈的操作数b大于等于出栈的操作数a(a≤b),因此输出序列的总数目=由左而右扫描由n个1和n个0组成的2n位二进制数,1的累计数不小于0的累计数的方案种数。4、给顶节点组成二叉树的问题。
给定N个节点,能构成多少种形状不同的二叉树?
(一定是二叉树!先去一个点作为顶点,然后左边依次可以取0至N-1个相对应的,右边是N-1到0个,两两配对相乘,就是h(0)*h(n-1) + h(2)*h(n-2) + ...... + h(n-1)h(0)=h(n))
(能构成h(N)个)
在2n位二进制数中填入n个1的方案数为c(2n,n),不填1的其余n位自动填0。从中减去不符合要求(由左而右扫描,0的累计数大于1的累计数)的方案数即为所求。
不符合要求的数的特征是由左而右扫描时,必然在某一奇数位2m+1位上首先出现m+1个0的累计数和m个1的累计数,此后的2(n-m)-1位上有n-m个 1和n-m-1个0。如若把后面这2(n-m)-1位上的0和1互换,使之成为n-m个0和n-m-1个1,结果得1个由n+1个0和n-1个1组成的2n位数,即一个不合要求的数对应于一个由n+1个0和n-1个1组成的排列。
反过来,任何一个由n+1个0和n-1个1组成的2n位二进制数,由于0的个数多2个,2n为偶数,故必在某一个奇数位上出现0的累计数超过1的累计数。同样在后面部分0和1互换,使之成为由n个0和n个1组成的2n位数,即n+1个0和n-1个1组成的2n位数必对应一个不符合要求的数。
因而不合要求的2n位数与n+1个0,n-1个1组成的排列一一对应。
显然,不符合要求的方案数为c(2n,n+1)。由此得出输出序列的总数目=c(2n,n)-c(2n,n+1)=1/(n+1)*c(2n,n)。
(这个公式的下标是从h(0)=1开始的)作者:Hackbuteer1 发表于 16:40:40
阅读:365 评论:4
1、微机中1K字节表示的二进制位数是()
2、设C语言中,一个int型数据在内存中占2个字节,则unsigned int 型数据的取值范围为()
A、0--- 255
B、0--- 32767
C、0--- 65535
3、在C语言中,要求运算数必须是整型的运算符是()
D、%4、下面程序段的运行结果是()
char c[5] = {'a','b','\0','c','\0'};
printf("%s",c);A、'a"b'
(其中_表示空格)
5、下列关于数组的初始化正确的是()
A、 char str[2] = {"a","b"}
B、 char str[2][3] = {"a","b"}
C、 char str[2][3] = {{'a','b'},{'e','f'},{'g','h'}}
D、 char str[] = {"a","b"}
6、判断字符串a和b是否相等,应当使用()
A、if(a==b)
B、if(a=b)
C、if(strcpy(a,b))
D、if(strcmp(a,b))
7、一直inta[3][4];则下列能表示a[1][2]元素值的是()
A、*(*(a+1)+2)
B、*(a+1+2)
C、(&a[0]+1)[2]
D、*(a[0]+1)
8、若希望当A的值为奇数时,表达式的值为真,A的值为偶数时,表达式的值为假,则以下不能满足要求的表达式是()
B、!(A%2==0)
C、!(A%2)
9、以下哪项可以用来释放 p = malloc() 分配的内存()
A、free(p)
B、delete p
C、delete []p
D、sizeof p
10、下列有关静态成员函数的描述中,正确的是()
A、静态数据成员可以再类体内初始化
B、静态数据成员不可以被类对象调用
C、静态数据成员不受private控制符作用
D、静态数据成员可以直接用类名调用
11、按e1、e2、e3、e4的次序进栈(中间可能有出栈操作,例如e1进栈后出栈,e2再进栈),则可能的出栈序列是()A、e3、e1、e4、e2
B、e2、e4、e3、e1
C、e3、e4、e1、e2
D、任意序列
12、某二叉树结点的中序序列为A、B、C、D、E、F、G,后序序列为B、D、C、A、F、G、E,该二叉树对应的树林包括多少棵树()
13、单链表的每个结点包括一个指针link,它指向该结点的后继结点,现要将指针q指向的新结点插入到指针p指向的单链表结点之后,下面的操作序列中哪一个是正确的?
A、q = p-& p-&link = q-&link
B、p-&link = q-& q = p-&linkC、q-&link = p-& p-&link = q
D、p-&link = q-&link = p-&
14、函数原型void fun(int a,int b=5,char c='*');下面的调用中不合法的是()
A、fun(4,1)
B、fun(99)
C、fun(11,2,'a')
D、fun(15,'*')
15、以下叙述中不正确的是()
A、在不同的函数中可以使用相同名字的变量
B、函数中的形式参数是局部变量
C、在一个函数内定义的变量只在本函数范围内有效D、在一个函数内的复合语句中定义的变量在本函数范围内有效(只在复合语句中有效)
16、设有一下宏定义:
#define N 3
#define Y(n) ((N+1)*n)
则执行语句:z=2*(N+Y(5+1))后的z值为()
17、以下程序程序的运行结果是()
int main(void)
char a[]={"programming"},b[]={"language"};
char *p1,*p2;
p1=a,p2=b;
for(i=0;i&7;i++)
if(*(p1+i)==*(p2+i))
printf("%c",*(p1+i));
18、若有以下程序段:
int a[]={4,0,2,3,1},i,j,t;
for(i=1;i&5;i++)
while(j&=0 && t&a[j])
a[j+1]=a[j];
}A、对数组a进行插入排序(升序)
B、对数组a进行插入排序(降序)
C、对数组a进行选择排序(升序)
D、对数组a进行选择排序(降序)19、以下程序的输出结果是()
#define P 3
int F(int x)
return (P*x*x);
void main()
printf("%d\n",F(3+5));
C、29D、77
20、以下代码中,A的构造函数和析构函数分别执行了几次()
A *pa = new A[10];
21、在顺序表{3、6、8、10、12、15、16、18、21、25、30}中,用二分法查找关键码值11,所需的关键码比较次数是()
22、若int占2个字节,char 占1个字节,float占4个字节,sizeof(xc)的大小是()
struct stu
char b[5];
int bh[2];
char xm[8];
23、设二叉树根结点的层次为0,一棵深度(高度)为k的满二叉树和同样深度的完全二叉树各有f个结点和c个结点,下列关系式不正确的是()
C、f=2^k+1
24、关于引用和指针的区别,下列叙述错误的是()
A、引用必须初始化,指针不必
B、指针初始化以后不能被改变,引用可以改变所指的对象
C、删除空指针是无害的,不能删除引用
D、不存在指向空值的引用,但是存在指向空值的指针
25、属于网络层协议的是()
26、STL中的哪种结构在增加成员时可能会引起原有数据成员的存储位置发生变动()
27、windows消息调度机制是()
A、指令队列
B、指令堆栈
C、消息队列
D、消息堆栈
28、在排序方法中,关键码比较次数和记录的初始排列无关的是()
A、Shell排序
B、归并排序
C、直接插入排序
D、选择排序
29、假设A为抽象类,下列声明()是正确的A、A fun(int );
C、int fun(A)
抽象类不能定义对象。但是可以作为指针或者引用类型使用。
30、如果类的定义如下,则以下代码正确并且是良好编程风格的是()
A、std::auto_ptr&Object& pObj(new Object);
B、std::vector&std::auto_ptr&Object*&& object_
C、std::auto_ptr&Object*& pObj(new Object);
D、std::vector&std::auto_ptr&Object&& object_
二、填空题1、写出float x 与零值比较的if语句。
不可将浮点变量用“==”或“!=”与数字比较,应该设法转化成“&=”或“&=”此类形式。
if(x&0.0000001
x&-0.0000001)
2、在32位系统中,char str[]="xuelei"; char *p = sizeof(str)=() ,sizeof(p)=() ,sizeof(*p)=()
答案分别是: 7、4、1,分别对数组、指针和一个字符类型求大小。。
3、Internet物理地址和IP地址转换采用什么协议?
4、char a[2][2][3] = {{{1,6,3},{5,4,15}},{{3,5,33},{23,12,7}}};
for(int i = 0;i&12;i++)
printf("%d",
);在空格处填上合适的语句,顺序打印出a中的数字。
答案:a[i/6][(i/3)%2][i%3];这道题目是多维数组的输出问题,这里要考虑的是每维数字的取值顺序问题:第一维,前六次循环都取0,后六次取1,于是i/6可以满足要求;第二维,前3次为0,再3次为1,再3次为0,再3次为1,用量化的思想,i/3把12个数字分为4组每组3个,量化为0、1、2、3,为要得到0、1、0、1我们这里就需要对(0、1、2、3)%2=(0、1、0、1),于是(i/3)%2;最后一维我们需要的是(0、1、2;0、1、2;0、1、2;0、1、2;)我们就填上i%3。
5、以下函数查找一个整数数组中第二大的数,请填空。
const int MINNUMBER = -32767;
int find_sec_max(int data[],int count)
int maxnumber = data[0];
int sec_max = MINNUMBER;
for(int i = 1;i & i++)
if(data[i] & maxnumber)
if(data[i] & sec_max)
return sec_
}上面的三个空格处依次应该填上:sec_max =
maxnumber = data[i];
sec_max = data[i];
6、下面程序可从1....n中随机输出m个不重复的数,请填空。
knuth(int n,int m)
srand((unsigned)time(NULL));
for(int i = 0;i &i++)
if(_________)
cout&&i&&"\n";
______________
分别为:rand()%(n-i)&m
7、以下prim函数的功能是分解质因数,请填空。
void prim(int m,int n)
while(_________)
______________;
prim(m,n);
void main()
int n = 435234;
prim(n,2);
}答案分别为:m%n
和 m/=n8、程序改错。
int fun(vector&int&& val)
copy(val.begin() , val.end() , ostream_iterator&int&(cout,"\n"));
void main()
int a[5] = {1,2,3,4,5};
vector&int&
copy(a , a + 5 , v.begin());
fun(vector&int&(v));
prim(n,2);
}错误的代码和改正后的代码分别为:
9、C++中const有什么用途(至少说出三种):1、便于进行类型检查;2、可以节省空间避免不必要的内存分配,提高了效率;3、保护被修饰的对象,防止意外修改,增强程序的健壮性。10、下面程序的功能是输出数组的全排列,请填空。
void perm(int list[],int k,int m)
if(_______)
copy(list,list+m,ostream_iterator&int&(cout," "));
for(int i = i &= ++i)
swap(&list[k] , &list[i]);
______________;
swap(&list[k] , &list[i]);
void main()
int list[] = {1,2,3,4,5};
perm(list,0,sizeof(list)/sizeof(int)-1);
}答案分别是: k == m 和 perm(list , k+1 , m)
作者:Hackbuteer1 发表于 16:04:40
阅读:495 评论:8
今天看了一下C++ Primer中关于const用法的介绍,讲得很好, 收益匪浅,于是做一个总结,方便以后再次查看。
但是c++在c的基础上新增加的几点优化也是很耀眼的,就const直接可以取代c中的#define以下几点很重要,学不好后果也也很严重。 一、const变量
1、限定符声明变量只能被读
const int i=5;
i=j;  //非法,导致编译错误
j=i;  //合法
2、 必须初始化
const int i=5;    //合法
const int j;      //非法,导致编译错误
3、在另一连接文件中引用const常量
extern const int i;    //合法
extern const int j=10;  //非法,常量不可以被再次赋值
4、便于进行类型检查
用const方法可以使编译器对处理内容有更多了解。
#define I=10
const long &i=10;  /*dapingguo提醒:由于编译器的优化,使得在const long i=10; 时i不被分配内存,而是已10直接代入以后的引用中,以致在以后的代码中没有错误,为达到说教效果,特别地用&i明确地给出了i的内存分配。不过一旦你关闭所有优化措施,即使const long i=10;也会引起后面的编译错误。*/
char h=I;      //没有错
char h=i;      //编译警告,可能由于数的截短带来错误赋值。
5、可以避免不必要的内存分配
#define STRING "abcdefghijklmnn"
const char string[]="abcdefghijklmn";
printf(STRING);  //为STRING分配了第一次内存
printf(string);  //为string一次分配了内存,以后不再分配
printf(STRING);  //为STRING分配了第二次内存
printf(string);
由于const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝。
6、可以通过函数对常量进行初始化
int value();
const int i=value();
dapingguo说:假定对ROM编写程序时,由于目标代码的不可改写,本语句将会无效,不过可以变通一下:
const int &i=value();
只要令i的地址处于ROM之外,即可实现:i通过函数初始化,而其值有不会被修改。
7、是不是const的常量值一定不可以被修改呢?
观察以下一段代码:
const int i=0;
int *p=(int*)&i;
通过强制类型转换,将地址赋给变量,再作修改即可以改变const常量值。
8、请分清数值常量和指针常量,以下声明颇为玩味:
int ii=0;
const int i=0;            //i是常量,i的值不会被修改
const int *p1i=&i;        //指针p1i所指内容是常量,可以不初始化
int  * const p2i=ⅈ    //指针p2i是常量,所指内容可修改
const int * const p3i=&i; //指针p3i是常量,所指内容也是常量
p1i=ⅈ                  //合法
*p2i=100;                //合法
在好长一收段时间我被const困惑,看到const关键字,C++程序员首先想到的可能是const常量,如果只知道用const定义是常量,那么相当于把火药仅用于制作鞭炮。const更大的魅力是它可以修饰函数的参数、返回值,甚至函数的定义体。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。所以很多C++程序设计书籍建议:"Use const whenever you need"。
二、const成员函数
任何不会修改数据成员的函数都应该声明为const类型。如果在编写const成员函数时,不慎修改了数据成员,或者调用了其它非const成员函数,编译器将指出错误,这无疑会提高程序的健壮性。以下程序中,类stack的成员函数GetCount仅用于计数,从逻辑上讲GetCount应当为const函数。编译器将指出GetCount函数中的错误。
class Stack
int m_data[100];
void Push(int elem);
int Pop(void);
int GetCount(void)
//const成员函数
int Stack::GetCount(void) const
//编译错误,企图修改数据成员m_num
//编译错误,企图非const成员函数
}const成员函数的声明看起来怪怪的:const关键字只能放在函数声明的尾部,大概是因为其它地方都已经被占用了。
作者:Hackbuteer1 发表于 20:58:33
阅读:281 评论:3
单例模式也称为单件模式、单子模式,可能是使用最广泛的设计模式。其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。有很多地方需要这样的功能模块,如系统的日志输出,GUI应用必须是单鼠标,MODEM的联接需要一条且只需要一条电话线,操作系统只能有一个窗口管理器,一台PC连一个键盘。
单例模式有许多种实现方法,在C++中,甚至可以直接用一个全局变量做到这一点,但这样的代码显的很不优雅。 使用全局对象能够保证方便地访问实例,但是不能保证只声明一个对象——也就是说除了一个全局实例外,仍然能创建相同类的本地实例。
《设计模式》一书中给出了一种很不错的实现,定义一个单例类,使用类的私有静态指针变量指向类的唯一实例,并用一个公有的静态方法获取该实例。
单例模式通过类本身来管理其唯一实例,这种特性提供了解决问题的方法。唯一的实例是类的一个普通对象,但设计这个类时,让它只能创建一个实例并提供对此实例的全局访问。唯一实例类Singleton在静态成员函数中隐藏创建实例的操作。习惯上把这个成员函数叫做Instance(),它的返回值是唯一实例的指针。定义如下:
class CSingleton
CSingleton()
//构造函数是私有的
static CSingleton *m_pI
static CSingleton * GetInstance()
if(m_pInstance == NULL)
//判断是否第一次调用
m_pInstance = new CSingleton();
return m_pI
};用户访问唯一实例的方法只有GetInstance()成员函数。如果不通过这个函数,任何创建实例的尝试都将失败,因为类的构造函数是私有的。GetInstance()使用懒惰初始化,也就是说它的返回值是当这个函数首次被访问时被创建的。这是一种防弹设计——所有GetInstance()之后的调用都返回相同实例的指针:
CSingleton* p1 = CSingleton :: GetInstance();
CSingleton* p2 = p1-&GetInstance();
CSingleton & ref = * CSingleton :: GetInstance();
对GetInstance稍加修改,这个设计模板便可以适用于可变多实例情况,如一个类允许最多五个实例。
单例类CSingleton有以下特征:
它有一个指向唯一实例的静态指针m_pInstance,并且是私有的;
它有一个公有的函数,可以获取这个唯一的实例,并且在需要的时候创建该实例;
它的构造函数是私有的,这样就不能从别处创建该类的实例。
大多数时候,这样的实现都不会出现问题。有经验的读者可能会问,m_pInstance指向的空间什么时候释放呢?更严重的问题是,该实例的析构函数什么时候执行?
如果在类的析构行为中有必须的操作,比如关闭文件,释放外部资源,那么上面的代码无法实现这个要求。我们需要一种方法,正常的删除该实例。
可以在程序结束时调用GetInstance(),并对返回的指针掉用delete操作。这样做可以实现功能,但不仅很丑陋,而且容易出错。因为这样的附加代码很容易被忘记,而且也很难保证在delete之后,没有代码再调用GetInstance函数。
一个妥善的方法是让这个类自己知道在合适的时候把自己删除,或者说把删除自己的操作挂在操作系统中的某个合适的点上,使其在恰当的时候被自动执行。
我们知道,程序在结束的时候,系统会自动析构所有的全局变量。事实上,系统也会析构所有的类的静态成员变量,就像这些静态成员也是全局变量一样。利用这个特征,我们可以在单例类中定义一个这样的静态成员变量,而它的唯一工作就是在析构函数中删除单例类的实例。如下面的代码中的CGarbo类(Garbo意为垃圾工人):class CSingleton
CSingleton()
static CSingleton *m_pI
class CGarbo
//它的唯一工作就是在析构函数中删除CSingleton的实例
if(CSingleton::m_pInstance)
delete CSingleton::m_pI
static CGarbo G
//定义一个静态成员变量,程序结束时,系统会自动调用它的析构函数
static CSingleton * GetInstance()
if(m_pInstance == NULL)
//判断是否第一次调用
m_pInstance = new CSingleton();
return m_pI
类CGarbo被定义为CSingleton的私有内嵌类,以防该类被在其他地方滥用。
程序运行结束时,系统会调用CSingleton的静态成员Garbo的析构函数,该析构函数会删除单例的唯一实例。
使用这种方法释放单例对象有以下特征:
在单例类内部定义专有的嵌套类;
在单例类内定义私有的专门用于释放的静态成员;
利用程序在结束时析构全局变量的特性,选择最终的释放时机;
使用单例的代码不需要任何操作,不必关心对象的释放。
进一步的讨论但是添加一个类的静态对象,总是让人不太满意,所以有人用如下方法来重现实现单例和解决它相应的问题,代码如下:
class CSingleton
CSingleton()
//构造函数是私有的
static CSingleton & GetInstance()
//局部静态变量
};使用局部静态变量,非常强大的方法,完全实现了单例的特性,而且代码量更少,也不用担心单例销毁的问题。
但使用此种方法也会出现问题,当如下方法使用单例时问题来了,
Singleton singleton = Singleton :: GetInstance();
这么做就出现了一个类拷贝的问题,这就违背了单例的特性。产生这个问题原因在于:编译器会为类生成一个默认的构造函数,来支持类的拷贝。最后没有办法,我们要禁止类拷贝和类赋值,禁止程序员用这种方式来使用单例,当时领导的意思是GetInstance()函数返回一个指针而不是返回一个引用,函数的代码改为如下:
class CSingleton
CSingleton()
//构造函数是私有的
static CSingleton * GetInstance()
//局部静态变量
但我总觉的不好,为什么不让编译器不这么干呢。这时我才想起可以显示的生命类拷贝的构造函数,和重载 = 操作符,新的单例类如下:
class CSingleton
CSingleton()
//构造函数是私有的
CSingleton(const CSingleton &);
CSingleton & operator = (const CSingleton &);
static CSingleton & GetInstance()
//局部静态变量
};关于Singleton(const Singleton);和 Singleton & operate = (const Singleton&);函数,需要声明成私有的,并且只声明不实现。这样,如果用上面的方式来使用单例时,不管是在友元类中还是其他的,编译器都是报错。
不知道这样的单例类是否还会有问题,但在程序中这样子使用已经基本没有问题了。
作者:Hackbuteer1 发表于 10:08:40
阅读:313 评论:2
全排列在笔试面试中很热门,因为它难度适中,既可以考察递归实现,又能进一步考察非递归的实现,便于区分出考生的水平。所以在百度和迅雷的校园招聘以及程序员和软件设计师的考试中都考到了,因此本文对全排列作下总结帮助大家更好的学习和理解。对本文有任何补充之处,欢迎大家指出。
首先来看看题目是如何要求的(百度迅雷校招笔试题)。
一、字符串的排列
用C++写一个函数, 如 Foo(const char *str), 打印出 str 的全排列,
如 abc 的全排列: abc, acb, bca, dac, cab, cba一、全排列的递归实现
为方便起见,用123来示例下。123的全排列有123、132、213、231、312、321这六种。首先考虑213和321这二个数是如何得出的。显然这二个都是123中的1与后面两数交换得到的。然后可以将123的第二个数和每三个数交换得到132。同理可以根据213和321来得231和312。因此可以知道——全排列就是从第一个数字起每个数分别与它后面的数字交换。找到这个规律后,递归的代码就很容易写出来了:
#include&iostream&
#include&assert.h&
void Permutation(char* pStr, char* pBegin)
assert(pStr && pBegin);
if(*pBegin == '\0')
printf("%s\n",pStr);
for(char* pCh = pB *pCh != '\0'; pCh++)
swap(*pBegin,*pCh);
Permutation(pStr, pBegin+1);
swap(*pBegin,*pCh);
int main(void)
char str[] = "abc";
Permutation(str,str);
另外一种写法:
//k表示当前选取到第几个数,m表示共有多少个数
void Permutation(char* pStr,int k,int m)
assert(pStr);
if(k == m)
static int num = 1;
//局部静态变量,用来统计全排列的个数
printf("第%d个排列\t%s\n",num++,pStr);
for(int i = i &= i++)
swap(*(pStr+k),*(pStr+i));
Permutation(pStr, k + 1 , m);
swap(*(pStr+k),*(pStr+i));
int main(void)
char str[] = "abc";
Permutation(str , 0 , strlen(str)-1);
}如果字符串中有重复字符的话,上面的那个方法肯定不会符合要求的,因此现在要想办法来去掉重复的数列。
二、去掉重复的全排列的递归实现
由于全排列就是从第一个数字起每个数分别与它后面的数字交换。我们先尝试加个这样的判断——如果一个数与后面的数字相同那么这二个数就不交换了。如122,第一个数与后面交换得212、221。然后122中第二数就不用与第三个数交换了,但对212,它第二个数与第三个数是不相同的,交换之后得到221。与由122中第一个数与第三个数交换所得的221重复了。所以这个方法不行。
换种思维,对122,第一个数1与第二个数2交换得到212,然后考虑第一个数1与第三个数2交换,此时由于第三个数等于第二个数,所以第一个数不再与第三个数交换。再考虑212,它的第二个数与第三个数交换可以得到解决221。此时全排列生成完毕。
这样我们也得到了在全排列中去掉重复的规则——去重的全排列就是从第一个数字起每个数分别与它后面非重复出现的数字交换。下面给出完整代码:#include&iostream&
#include&assert.h&
//在[nBegin,nEnd)区间中是否有字符与下标为pEnd的字符相等
bool IsSwap(char* pBegin , char* pEnd)
for(p = pB p & pE p++)
if(*p == *pEnd)
void Permutation(char* pStr , char *pBegin)
assert(pStr);
if(*pBegin == '\0')
static int num = 1;
//局部静态变量,用来统计全排列的个数
printf("第%d个排列\t%s\n",num++,pStr);
for(char *pCh = pB *pCh != '\0'; pCh++)
//第pBegin个数分别与它后面的数字交换就能得到新的排列
if(IsSwap(pBegin , pCh))
swap(*pBegin , *pCh);
Permutation(pStr , pBegin + 1);
swap(*pBegin , *pCh);
int main(void)
char str[] = "baa";
Permutation(str , str);
}OK,到现在我们已经能熟练写出递归的方法了,并且考虑了字符串中的重复数据可能引发的重复数列问题。那么如何使用非递归的方法来得到全排列了?
三、全排列的非递归实现
要考虑全排列的非递归实现,先来考虑如何计算字符串的下一个排列。如"1234"的下一个排列就是"1243"。只要对字符串反复求出下一个排列,全排列的也就迎刃而解了。
如何计算字符串的下一个排列了?来考虑"926520"这个字符串,我们从后向前找第一双相邻的递增数字,"20"、"52"都是非递增的,"26 "即满足要求,称前一个数字2为替换数,替换数的下标称为替换点,再从后面找一个比替换数大的最小数(这个数必然存在),0、2都不行,5可以,将5和2交换得到"956220",然后再将替换点后的字符串"6220"颠倒即得到"950226"。
对于像“4321”这种已经是最“大”的排列,采用STL中的处理方法,将字符串整个颠倒得到最“小”的排列"1234"并返回false。这样,只要一个循环再加上计算字符串下一个排列的函数就可以轻松的实现非递归的全排列算法。按上面思路并参考STL中的实现源码,不难写成一份质量较高的代码。值得注意的是在循环前要对字符串排序下,可以自己写快速排序的代码(请参阅《白话经典算法之六 快速排序 快速搞定》),也可以直接使用VC库中的快速排序函数(请参阅《使用VC库函数中的快速排序函数》)。下面列出完整代码:
#include&iostream&
#include&algorithm&
#include&cstring&
#include&assert.h&
//反转区间
void Reverse(char* pBegin , char* pEnd)
while(pBegin & pEnd)
swap(*pBegin++ , *pEnd--);
//下一个排列
bool Next_permutation(char a[])
assert(a);
char *p , *q , *pF
char *pEnd = a + strlen(a) - 1;
if(a == pEnd)
while(p != a)
if(*p & *q)
//找降序的相邻2数,前一个数即替换数
//从后向前找比替换点大的第一个数
pFind = pE
while(*pFind & *p)
swap(*p , *pFind);
//替换点后的数全部反转
Reverse(q , pEnd);
Reverse(a , pEnd);
//如果没有下一个排列,全部反转后返回false
int cmp(const void *a,const void *b)
return int(*(char *)a - *(char *)b);
int main(void)
char str[] = "bac";
int num = 1;
qsort(str , strlen(str),sizeof(char),cmp);
printf("第%d个排列\t%s\n",num++,str);
}while(Next_permutation(str));
}至此我们已经运用了递归与非递归的方法解决了全排列问题,总结一下就是:
1、全排列就是从第一个数字起每个数分别与它后面的数字交换。
2、去重的全排列就是从第一个数字起每个数分别与它后面非重复出现的数字交换。
3、全排列的非递归就是由后向前找替换数和替换点,然后由后向前找第一个比替换数大的数与替换数交换,最后颠倒替换点后的所有数据。二、字符串的组合
题目:输入一个字符串,输出该字符串中字符的所有组合。举个例子,如果输入abc,它的组合有a、b、c、ab、ac、bc、abc。
上面我们详细讨论了如何用递归的思路求字符串的排列。同样,本题也可以用递归的思路来求字符串的组合。
假设我们想在长度为n的字符串中求m个字符的组合。我们先从头扫描字符串的第一个字符。针对第一个字符,我们有两种选择:第一是把这个字符放到组合中去,接下来我们需要在剩下的n-1个字符中选取m-1个字符;第二是不把这个字符放到组合中去,接下来我们需要在剩下的n-1个字符中选择m个字符。这两种选择都很容易用递归实现。下面是这种思路的参考代码:#include&iostream&
#include&vector&
#include&cstring&
#include&assert.h&
void Combination(char *string ,int number,vector&char& &result);
void Combination(char *string)
assert(string != NULL);
vector&char&
int i , length = strlen(string);
for(i = 1 ; i &= ++i)
Combination(string , i ,result);
void Combination(char *string ,int number , vector&char& &result)
assert(string != NULL);
if(number == 0)
static int num = 1;
printf("第%d个组合\t",num++);
vector&char&::iterator iter = result.begin();
for( ; iter != result.end() ; ++iter)
printf("%c",*iter);
printf("\n");
if(*string == '\0')
result.push_back(*string);
Combination(string + 1 , number - 1 , result);
result.pop_back();
Combination(string + 1 , number , result);
int main(void)
char str[] = "abc";
Combination(str);
由于组合可以是1个字符的组合,2个字符的字符……一直到n个字符的组合,因此在函数void Combination(char* string),我们需要一个for循环。另外,我们一个vector来存放选择放进组合里的字符。
字符串全排列扩展----八皇后问题
题目:在8×8的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后不得处在同一行、同一列或者同一对角斜线上。下图中的每个黑色格子表示一个皇后,这就是一种符合条件的摆放方法。请求出总共有多少种摆法。
这就是有名的八皇后问题。解决这个问题通常需要用递归,而递归对编程能力的要求比较高。因此有不少面试官青睐这个题目,用来考察应聘者的分析复杂问题的能力以及编程的能力。
由于八个皇后的任意两个不能处在同一行,那么这肯定是每一个皇后占据一行。于是我们可以定义一个数组ColumnIndex[8],数组中第i个数字表示位于第i行的皇后的列号。先把ColumnIndex的八个数字分别用0-7初始化,接下来我们要做的事情就是对数组ColumnIndex做全排列。由于我们是用不同的数字初始化数组中的数字,因此任意两个皇后肯定不同列。我们只需要判断得到的每一个排列对应的八个皇后是不是在同一对角斜线上,也就是数组的两个下标i和j,是不是i-j==ColumnIndex[i]-Column[j]或者j-i==ColumnIndex[i]-ColumnIndex[j]。
关于排列的详细讨论,详见上面的讲解。
接下来就是写代码了。思路想清楚之后,编码并不是很难的事情。下面是一段参考代码:
#include&iostream&
int g_number = 0;
void Permutation(int * , int
void Print(int * , int );
void EightQueen( )
const int queens = 8;
int ColumnIndex[queens];
for(int i = 0 ; i & ++i)
ColumnIndex[i] =
Permutation(ColumnIndex , queens , 0);
bool Check(int ColumnIndex[] , int length)
for(i = 0 ; i & ++i)
for(j = i + 1 ; j & ++j)
if( i - j == ColumnIndex[i] - ColumnIndex[j] || j - i == ColumnIndex[i] - ColumnIndex[j])
//在正、副对角线上
void Permutation(int ColumnIndex[] , int length , int index)
if(index == length)
if( Check(ColumnIndex , length) )
//检测棋盘当前的状态是否合法
Print(ColumnIndex , length);
for(int i = i & ++i)
swap(ColumnIndex[index] , ColumnIndex[i]);
Permutation(ColumnIndex , length , index + 1);
swap(ColumnIndex[index] , ColumnIndex[i]);
void Print(int ColumnIndex[] , int length)
printf("%d\n",g_number);
for(int i = 0 ; i & ++i)
printf("%d ",ColumnIndex[i]);
printf("\n");
int main(void)
EightQueen();
}转载:http://zhedahht.blog.163.co
作者:Hackbuteer1 发表于 11:24:26
阅读:1544 评论:5
1、以下三条输出语句分别输出什么?
char str1[] = "abc";
char str2[] = "abc";
const char str3[] = "abc";
const char str4[] = "abc";
const char* str5 = "abc";
const char* str6 = "abc";
cout && boolalpha && ( str1==str2 ) && // 输出什么?
cout && boolalpha && ( str3==str4 ) && // 输出什么?
cout && boolalpha && ( str5==str6 ) && // 输出什么?
答:分别输出false,false,true。str1和str2都是字符数组,每个都有其自己的存储区,它们的值则是各存储区首地址,不等;str3和str4同上,只是按const语义,它们所指向的数据区不能修改。str5和str6并非数组而是字符指针,并不分配存储区,其后的“abc”以常量形式存于静态数据区,而它们自己仅是指向该区首地址的指针,所以相等。
2、下面代码的输出是什么?
float a = 1.0f;
cout&& (int)a &&
cout&& (int&)a &&
cout && boolalpha && ( (int)a==(int&)a ) && // 输出什么?
float b = 0.0f;
cout&& (int)b &&
cout&& (int&)b &&
cout && boolalpha && ( (int)b==(int&)b ) && // 输出什么?
浮点数的 1.0f 在内存里是这样表示的:
这个32位二进制数被当作整数输出就是:
而整数的 1 在内存里是这样表示的:
所以 (int)a != (int&)a
浮点的0和整数的0 在内存里都是:
所以 (int)b == (int&)b
3、以下代码中的两个sizeof用法有问题吗?
void UpperCase( char str[] ) // 将str 中的小写字母转换成大写字母
for( size_t i=0; i&sizeof(str)/sizeof(str[0]); ++i )
if( 'a'&=str[i] && str[i]&='z' )
str[i] -= ('a'-'A' );
int main(void)
char str[] = "aBcDe";
cout && "str字符长度为: " && sizeof(str)/sizeof(str[0]) &&
UpperCase( str );
cout && str &&
}4、非C++内建型别A和B,在哪几种情况下B能隐式转化为A?
5、以下代码有什么问题?
struct Test
Test(int ) { }
Test() { }
void fun() { }
int main(void)
Test a(1);
}6、以下代码有什么问题?
cout&& (true?1:"0") &&
7、以下代码能够编译通过吗,为什么?
int main(void)
unsigned int const size1 = 2;
char str1[ size1 ];
unsigned int temp = 0;
unsigned int const size2 =
char str2[ size2 ];
}8、以下反向遍历array数组的方法有什么错误?int main(void)
array.push_back( 1 );
array.push_back( 2 );
array.push_back( 3 );
for( vector::size_type i=array.size()-1; i&=0; --i )
// 反向遍历array数组
cout && array[i] &&
9、以下代码中的输出语句输出吗,为什么?
struct CLS
CLS(int i): m_i( i ) {
int main(void)
cout && obj.m_i &&
}10、C++中的空类,默认产生哪些类成员函数?11、 以下代码有什么问题吗?
int main(void)
typedef vector IntA
array.push_back( 1 );
array.push_back( 2 );
array.push_back( 2 );
array.push_back( 3 );
// 删除array数组中所有的2
for( IntArray::iterator itor=array.begin(); itor!=array.end(); ++itor )
if( 2 == *itor )
array.erase( itor );
}12、 写一个函数,完成内存之间的拷贝。[考虑问题是否全面]
2、分别输出false和true。注意转换的应用。(int)a实际上是以浮点数a为参数构造了一个整型数,该整数的值是,(int&)a则是告诉编译器将a当作整数看(并没有做任何实质上的转换)。因为以整数形式存放和以浮点形式存放其内存数据是不一样的,因此两者不等。对b的两种转换意义同上,但是的整数形式和浮点形式其内存数据是一样的,因此在这种特殊情形下,两者相等(仅仅在数值意义上)。
注意,程序的输出会显示(int&)a=,这个值是怎么来的呢?前面已经说了,以浮点数形式存放在内存中,按ieee754规定,其内容为x0000803F(已考虑字节反序)。这也就是a这个变量所占据的内存单元的值。当(int&)a出现时,它相当于告诉它的上下文:“把这块地址当做整数看待!不要管它原来是什么。”这样,内容x0000803F按整数解释,其值正好就是(十进制数)。
通过查看汇编代码可以证实“(int)a相当于重新构造了一个值等于a的整型数”之说,而(int&)的作用则仅仅是表达了一个类型信息,意义在于为cout&&及==选择正确的重载版本。
3、答:函数内的sizeof有问题。根据语法,sizeof如用于数组,只能测出静态数组的大小,无法检测动态分配的或外部数组大小。函数外的str是一个静态定义的数组,因此其大小为,函数内的str实际只是一个指向字符串的指针,没有任何额外的与数组相关的信息,因此sizeof作用于上只将其当指针看,一个指针为个字节,因此返回。
a. class B : public A { ……} // B公有继承自A,可以是间接继承的
b. class B { operator A( ); } // B实现了隐式转化为A的转化
c. class A { A( const B& ); } // A实现了non-explicit的参数为B(可以有其他带默认值的参数)构造函数
d. A& operator= ( const A& ); // 赋值操作,虽不是正宗的隐式类型转换,但也勉强算一个
5、答:变量b定义出错。按默认构造函数定义对象,不需要加括号。
6、答:三元表达式“?:”问号后面的两个操作数必须为同一类型。
7、答:str2定义出错,size2非编译器期间常量,而数组定义要求长度必须为编译期常量。
8、答:首先数组定义有误,应加上类型参数:vector&int& array。其次vector::size_type被定义为unsigned int,即无符号数,这样作为循环变量的i为0时再减就会变成最大的整数,导致循环失去控制。
int main(void)
vector&int&
array.push_back(1);
array.push_back(2);
array.push_back(3);
for(int i = array.size() - 1 ; i &= 0 ; --i)
cout&&array[i]&&
}9、答:不能。在默认构造函数内部再调用带参的构造函数属用户行为而非编译器行为,亦即仅执行函数调用,而不会执行其后的初始化表达式。只有在生成对象时,初始化表达式才会随相应的构造函数一起调用。
class Empty
//缺省构造函数
Empty(const Empty &);
//拷贝构造函数
//析构函数
Empty & operator=(const Empty &);
//赋值运算符
Empty* operator&();
//取址运算符
const Empty* operator&()
//取址运算符const
};11、答:同样有缺少类型参数的问题。另外,每次调用“array.erase(itor);”,被删除元素之后的内容会自动往前移,导致迭代漏项,应在删除一项后使itor--,使之从已经前移的下一个元素起继续遍历。int main(void)
typedef vector&int& IntA
array.push_back( 1 );
array.push_back( 2 );
array.push_back( 2 );
array.push_back( 3 );
// 删除array数组中所有的2
for( IntArray::iterator itor=array.begin(); itor!=array.end(); ++itor )
if( 2 == *itor )
itor = array.erase( itor );
// 功能:由src所指内存区域复制count个字节到dest所指内存区域

我要回帖

更多关于 怎样的手掌才是正常的 的文章

 

随机推荐