最新腾讯,创新工场,淘宝等公司最新面试十三题(更新至24题)

 

曾记否,去年的10月份也同此刻一样,是找工作的高峰期,本博客便是最初由整理微软等公司面试题而发展而来的。如今,又即将迈入求职高峰期--10月份,而本人也正在找下一份工作中 ,所以,也不免关注了网上和我个人建的算法群Algorithms1-12群(第1-11群已满,Algorithms_12群,53403981 )内朋友发布和讨论的最新面试题。特此整理,以飨诸位。至于答案,望诸位共同讨论与思考。

自从公布Algorithms_9群-11群的群号以来,一般一个星期之内满员。不免被各位的热情所震撼(包括本文评论下奉献自己的思路的朋友,非常感谢)。希望,各位既然加进来,便多多参与讨论下文中的面试题,一起学习、思考,以期共同进步。谢谢。

最新面试十三题

好久没有好好享受思考了。ok,任何人有任何意见或问题,欢迎不吝指导:

  1. 五只猴子分桃。半夜,第一只猴子先起来,它把桃分成了相等的五堆,多出一只。于是,它吃掉了一个,拿走了一堆; 第二只猴子起来一看,只有四堆桃。于是把四堆合在一起,分成相等的五堆,又多出一个。于是,它也吃掉了一个,拿走了一堆;.....其他几只猴子也都是 这样分的。问:这堆桃至少有多少个?(朋友说,这是小学奥数题)。
    参考答案:先给这堆桃子加上4个,设此时共有X个桃子,最后剩下a个桃子.这样:
    第一只猴子分完后还剩:(1-1/5)X=(4/5)X;
    第二只猴子分完后还剩:(1-1/5)2X;
    第三只猴子分完后还剩:(1-1/5)3X;
    第四只猴子分完后还剩:(1-1/5)4X;
    第五只猴子分完后还剩:(1-1/5)5X=(1024/3125)X;
    得:a=(1024/3125)X;
    要使a为整数,X最小取3125.
    减去加上的4个,所以,这堆桃子最少有3121个。
  2. 已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10
    (参考答案:这题主要考的是对概率的理解。程序关键是要算出rand10,1到10,十个数字出现的考虑都为10%.根据排列组合,连续算两次rand7出现的组合数是7*7=49,这49种组合每一种出现考虑是相同的。怎么从49平均概率的转换为1到10呢?方法是:
    1.rand7执行两次,出来的数为a1.a2.
    2.如果a1*7+a2<40,b=(a1*7+a2)/4+1,如果a1*7*a2>=40,重复第一步)。参考代码如下所示:
    1. int rand7()
    2. {
    3. return rand()%7+1;
    4. }
    5. int rand10()
    6. {
    7. int a71,a72,a10;
    8. do
    9. {
    10. a71= rand7()-1;
    11. a72 = rand7()-1;
    12. a10 = a71 *7 + a72;
    13. } while (a10>= 40);
    14. return (a71*7+a72)/4+1;
    15. }
  3. 如果两个字符串的字符一样,但是顺序不一样,被认为是兄弟字符串,问如何在迅速匹配兄弟字符串(如,bad和adb就是兄弟字符串)。
  4. 要求设计一个DNS的Cache结构,要求能够满足每秒5000以上的查询,满足IP数据的快速插入,查询的速度要快。
  5. 一个未排序整数数组,有正负数,重新排列使负数排在正数前面,并且要求不改变原来的 相对顺序 比如: input: 1,7,-5,9,-12,15 ans: -5,-12,1,7,9,15 要求时间复杂度O(N),空间O(1) 。(此题一直没看到令我满意的答案,一般达不到题目所要求的:时间复杂度O(N),空间O(1)
  6. 淘宝面试题:有一个一亿节点的树,现在已知两个点,找这两个点的共同的祖先。
  7. 海量数据分布在100台电脑中,想个办法高效统计出这批数据的TOP10。(此题请参考本博客内其它文章)。
  8. 某服务器流量统计器,每天有1000亿的访问记录数据,包括时间、url、ip。设计系统实现记录数据的

    保存、管理、查询。要求能实现一下功能:
    (1)计算在某一时间段(精确到分)时间内的,某url的所有访问量。
    (2)计算在某一时间段(精确到分)时间内的,某ip的所有访问量。

  9.  

    假设某个网站每天有超过10亿次的页面访问量,出于安全考虑,网站会记录访问客户端访问的ip地址和对应的时间,如果现在已经记录了1000亿条数据,想统计一个指定时间段内的区域ip地址访问量,那么这些数据应该按照何种方式来组织,才能尽快满足上面的统计需求呢,
    设计完方案后,并指出该方案的优缺点,比如在什么情况下,可能会非常慢?(参考答案:用B+树来组织,非叶子节点存储(某个时间点,页面访问量),叶子节点是访问的IP地址。这个方案的优点是查询某个时间段内的IP访问量很快,但是要统计某个IP的访问次数或是上次访问时间就不得不遍历整个树的叶子节点。 或者可以建立二级索引,分别是时间和地点来建立索引。

  10.  

    腾讯1.服务器内存1G,有一个2G的文件,里面每行存着一个QQ号(5-10位数),怎么最快找出出现过最多次的QQ号。
    腾讯2.如何求根号2的值,并且按照我的需要列出指定小数位,比如根号2是1.141 我要列出1位小数就是1.1 2位就是1.14, 1000位就是1.141...... 等。。

  11.  

    给定一个字符串的集合,格式如:{aaa bbb ccc}, {bbb ddd},{eee fff},{ggg},{ddd hhh}要求将其中交集不为空的集合合并,要求合并完成后的集合之间无交集,例如上例应输出{aaa bbb ccc ddd hhh},{eee fff}, {ggg}。
  12.  

    创新工场面试题:abcde五人打渔,打完睡觉,a先醒来,扔掉1条鱼,把剩下的分成5分,拿一份走了;b再醒来,也扔掉1条,把剩下的分成5份,拿一份走了;然后cde都按上面的方法取鱼。问他们一共打了多少条鱼,写程序和算法实现。提示:共打了多少条鱼的结果有很多。但求最少打的鱼的结果是3121条鱼(应该找这5个人问问,用什么工具打了这么多条鱼)。(http://blog.csdn.net/nokiaguy/article/details/6800209 )。
  13. 我们有很多瓶无色的液体,其中有一瓶是毒药,其它都是蒸馏水,实验的小白鼠喝了以后会在5分钟后死亡,而喝到蒸馏水的小白鼠则一切正常。现在有5只小白鼠,请问一下,我们用这五只小白鼠,5分钟的时间,能够检测多少瓶液体的成分?
    淘宝2012笔试(研发类):http://topic.csdn.net/u/20110922/10/e4f3641a-1f31-4d35-80da-7268605d2d51.html一参考答案 )。

ok,这13道题加上此前本博客陆陆续续整理的微软面试187题:重启开源,分享无限--诚邀你加入微软面试 18 7 的解题中 ,至此,本博客内已经整理了整整200道 面试题。

同时,也算是由于本博客在开博不到一年的时间内2010.10.14-2011.09.19突破100万流量 而对读者的支持和青睐表示感谢。有任何问题或思路,欢迎不吝赐教(或者来信指导:[email protected] )。谢谢。July、二零一一年九月二十三日。

后续整理

以下是后续整理的最新面试题,不断更新中(2011.09.26).....

14 、腾讯最新面试题:服务器内存1G,有一个2G的文件,里面每行存着一个QQ号(5-10位数),怎么最快找出出现过最多次的QQ号。

15 、百度今天的笔试题:在一维坐标轴上有n个区间段,求重合区间最长的两个区间段。

16 、华为社招现场面试1:请使用代码计算1234567891011121314151617181920*2019181716151413121110987654321 。

华为面试2:1分2分5分的硬币,组成1角,共有多少种组合。

17 、百度笔试题:

一、系统有很多任务,任务之间有依赖,比如B依赖于A,则A执行完后B才能执行
(1)不考虑系统并行性,设计一个函数(Task *Ptask,int Task_num)不考虑并行度,最快的方法完成所有任务。
(2)考虑并行度,怎么设计
typedef struct{
int ID;
int * child;
int child_num;
}Task;
提供的函数:
bool doTask(int taskID);无阻塞的运行一个任务;
int waitTask(int timeout);返回运行完成的任务id,如果没有则返回-1;
bool killTask(int taskID);杀死进程

二、必答题(各种const)

 

1、解释下面ptr含义和不同
double* ptr = &value;
//ptr是一个指向double类型的指针,ptr的值可以改变,ptr所指向的value的值也可以改变
const double* ptr = &value
//ptr是一个指向const double类型的指针,ptr的值可以改变,ptr所指向的value的值不可以改变
double* const ptr=&value
//ptr是一个指向double类型的指针,ptr的值不可以改变,ptr所指向的value的值可以改变
const double* const ptr=&value
//ptr是一个指向const double类型的指针,ptr的值不可以改变,ptr所指向的value的值也不可以改变

 

 

2、去掉const属性,例: const double value = 0.0f; double* ptr = NULL;怎么才能让ptr指向value?
强制类型转换,去掉const属性,如ptr = <const_cast double *>(&value);

http://topic.csdn.net/u/20110925/16/e6248e53-1145-4815-8d24-9c9019d24bd8.html?seed=1665205011&r=75709169#r_75709169

18 、如果用一个循环数组q[0..m-1]表示队列时,该队列只有一个队列头指针front,不设队列尾指针rear,求这个队列中从队列投到队列尾的元素个数(包含队列头、队列尾)(华赛面试题、腾讯笔试题)。

19 、昨晚淘宝笔试题:

1. 设计相应的数据结构和算法,尽量高效的统计一片英文文章(总单词数目)里出现的所有英文单词,按照在文章中首次出现的顺序打印输出该单词和它的出现次数。

2、有一棵树(树上结点为字符串或者整数),请写代码将树的结构和数据写到一个文件中,并能通过读取该文件恢复树结构 。

20 、13个球一个天平,现知道只有一个和其它的重量不同,问怎样称才能用三次就找到那个球?(http://zhidao.baidu.com/question/66024735.html
)。

21 、搜狗笔试题:一个长度为n的数组a[0],a[1],...,a[n-1]。现在更新数组的名个元素,即a[0]变为a[1]到a[n-1]的积,a[1]变为a[0]和a[2]到a[n-1]的积,...,a[n-1]为a[0]到a[n-2]的积。
程序要求:
要求具有线性复杂度。
不能使用除法运算符。

参考答案@MESH4444:

3步搞定(假设乘法是一次运算)……
1、累乘:计算a1*a2, a1*a2*a3, ......, a1*a2*...*an——复杂度n-1
2、累乘:计算an*a(n-1), an*a(n-1)*a(n-2), ......, an*a(n-1)*a(n-2)*...*a1——复杂度n-1
3、求积:找到对应数值,直接再做一次乘法得结果——复杂度为n

这样,复杂度就是3n-2,也就是O(3n)

22 、腾讯高水平复试题:

1.有不同的手机终端,如iphone,安卓,Symbian,不同的终端处理不一样,设计一种服务器和算法实现对不同的终端的处理。
2.设计一种内存管理算法。
3.A向B发邮件,B收到后读取并发送收到,但是中间可能丢失了该邮件,怎么设计一种最节省的方法,来处理丢失问题。
4.设计一种算法求出算法复杂度 。
23 、人人笔试1:一个人上台阶可以一次上1个,2个,或者3个,问这个人上n层的台阶,总共有几种走法?
人人笔试2:在人人好友里,A和B是好友,B和C是好友,如果A 和C不是好友,那么C是A的二度好友,在一个有10万人的数据库里,如何在时间0(n)里,找到某个人的十度好友。
24 、淘宝算法面试题:两个用户之间可能互相认识,也可能是单向的认识,用什么数据结构来表示?如果一个用户不认识别人,而且别人也不认识他,那么他就是无效节点,如何找出这些无效节点?自定义数据接口并实现之,要求尽可能节约内存和空间复杂度。

更新至2011.09.29....

异常感谢本文评论中各位奉献的自己的思路 贴代码的时候,勿忘简单描述下思路 ,望各位继续思考和讨论,偶亦可多多学习与参考。同时,不断整理出新的面试题。July、2011.09.26。

79
6
查看评论
136楼 nirendao 昨天 21:01发表 [回复]
第一题的笨办法。
  1. int i = 0, count, tmp;
  2. while (1)
  3. {
  4. tmp = ++i;
  5. for (count = 0; count < 5; count++)
  6. {
  7. tmp = ((tmp-1) % 5 == 0)?(tmp-1)/5*4:-1;
  8. if (tmp <= 0)
  9. break ;
  10. }
  11. if (count == 5)
  12. break ;
  13. }
  14. printf( "The result is %d\n" , i);
int i = 0, count, tmp; while(1) { tmp = ++i; for(count = 0; count < 5; count++) { tmp = ((tmp-1) % 5 == 0)?(tmp-1)/5*4:-1; if(tmp <= 0) break; } if(count == 5) break; } printf("The result is %d\n", i);
135楼 renenglish 昨天 19:05发表 [回复]
第五题时间O(n),空间O(1)复杂度算法:
  1. #include <stdio.h>
  2. void nswapvalue( int *arr, int i , int j) { // change positive to negative
  3. int m = arr[i];
  4. arr[i] = arr[j];
  5. arr[j] = -m;
  6. }
  7. void pswapvalue( int *arr, int i , int j) { //change negative to positive
  8. int m = arr[i];
  9. arr[i] = -arr[j];
  10. arr[j] = m;
  11. }
  12. int swaploop( int *arr, int size){ //思想:执行一次循环,把所有负数置换到前面,可以保证负数的相对位置不变
  13. int cur = 0,count=0,i;
  14. for (i = 0 ;i < size; ++i){ // 把所有负数提前,并把置换到后面的整数变为负数
  15. if (arr[i]>0 && cur ==0){
  16. cur = i; //cur 始终指向最前面的整数
  17. }
  18. if (arr[i]<0 && cur < i){
  19. nswapvalue(arr,cur,i);
  20. ++cur;
  21. ++count; //记录负数的个数
  22. }
  23. }
  24. for (i = count ;i < size; ++i){ //处理原始负数以后的数据,并把上面变为负数的正数变回来
  25. if (arr[i]>0 && cur ==0){
  26. cur = i;
  27. }
  28. if (arr[i]<0 && cur < i){
  29. pswapvalue(arr,cur,i);
  30. ++cur;
  31. }
  32. }
  33. }
#include <stdio.h> void nswapvalue(int *arr,int i , int j) { // change positive to negative int m = arr[i]; arr[i] = arr[j]; arr[j] = -m; } void pswapvalue(int *arr,int i , int j) {//change negative to positive int m = arr[i]; arr[i] = -arr[j]; arr[j] = m; } int swaploop(int *arr,int size){//思想:执行一次循环,把所有负数置换到前面,可以保证负数的相对位置不变 int cur = 0,count=0,i; for(i = 0 ;i < size; ++i){ // 把所有负数提前,并把置换到后面的整数变为负数 if(arr[i]>0 && cur ==0){ cur = i; //cur 始终指向最前面的整数 } if(arr[i]<0 && cur < i){ nswapvalue(arr,cur,i); ++cur; ++count; //记录负数的个数 } } for(i = count ;i < size; ++i){ //处理原始负数以后的数据,并把上面变为负数的正数变回来 if(arr[i]>0 && cur ==0){ cur = i; } if(arr[i]<0 && cur < i){ pswapvalue(arr,cur,i); ++cur; } } }
Re: eagleatustb 昨天 19:46发表 [回复]
回复renenglish:已通过程序验证,结果不对
输入int arr[10] = { -1,2,3,4,-5,6,-7,8,-9,10 };
int size = 10;
出来的结果是:-1,-5,-7,-9,3,4,-2,8,6,10;
请验证!
134楼 jijiyuyisheng 昨天 17:14发表 [回复]
人人笔试题1:
int fun(int n)
{
int f;
if(n <= 3)
{
f = pow(double(2),(n-1));
}
else
{
f = fun(n - 1) + fun(n - 2) + fun(n - 3);
}
return f;
}
int main(void)
{
int n = 7;//台阶总数
int sum;
sum = fun(n);
printf("%d\n",sum);

}
Re: sxkj_flj 昨天 22:52发表 [回复]
回复jijiyuyisheng:这样递归重复计算很多,有两种方法
1.迭代
  1. int GetMaxStepNormal( int n)
  2. {
  3. if (n<=0) return 0;
  4. if (n==1) return 1;
  5. if (n==2) return 2;
  6. if (n==3) return 4;
  7. int r,r1=1,r2=2,r3=4;
  8. for ( int i=3;i<n;i++)
  9. {
  10. r=r1+r2+r3;
  11. r1=r2;
  12. r2=r3;
  13. r3=r;
  14. }
  15. return r;
  16. }
int GetMaxStepNormal(int n) { if(n<=0) return 0; if(n==1) return 1; if(n==2) return 2; if(n==3) return 4; int r,r1=1,r2=2,r3=4; for(int i=3;i<n;i++) { r=r1+r2+r3; r1=r2; r2=r3; r3=r; } return r; }

2.递归,注意保存以计算的结果
  1. <BR> int GetMaxStepMain( int , int *);<BR> int GetMaxStepRecurs( int n)<BR>{<BR> int * calc;<BR> int r;<BR> if (n<=0) return 0;<BR> calc= new int [n];<BR> if (NULL==calc) return 0;<BR> for ( int i=0;i<n;++i) calc<I>=0;<BR> r= GetMaxStepMain(n,calc);<BR> delete calc;<BR> return r;<BR>}<BR> int GetMaxStepMain( int n, int * a)<BR>{<BR> int t[3];<BR> if (n==1) return 1;<BR> if (n==2) return 2;<BR> if (n==3) return 4;<BR> <BR> for ( int i=3;i>0;i--)<BR> {<BR> if (a[n-i]==0) <BR> {<BR> t[i-1]=GetMaxStepMain(n-i,a);<BR> a[n-i]=t[i-1];<BR> }<BR> else <BR> {<BR> t[i-1]=a[n-i];<BR> }<BR> }<BR> return t[0]+t[1]+t[2];<BR>}<BR>
int GetMaxStepMain(int ,int*);
int GetMaxStepRecurs(int n)
{
int* calc;
int r;
if(n<=0) return 0;
calc=new int[n];
if(NULL==calc) return 0;
for(int i=0;i<n;++i) calc=0;
r= GetMaxStepMain(n,calc);
delete calc;
return r;
}
int GetMaxStepMain(int n,int* a)
{
int t[3];
if(n==1) return 1;
if(n==2) return 2;
if(n==3) return 4;
 
for(int i=3;i>0;i--)
{
if(a[n-i]==0) 
{
t[i-1]=GetMaxStepMain(n-i,a);
a[n-i]=t[i-1];
}
else
{
t[i-1]=a[n-i];
}
}
return t[0]+t[1]+t[2];
}

133楼 renenglish 昨天 16:55发表 [回复]
第三题O(n)复杂度算法:
  1. #include <stdio.h>
  2. #include <string.h>
  3. int brothstr( const char *s1, int len1, const char *s2, int len2){
  4. if (len1 != len2) return 0;
  5. int box[128] = {0};
  6. int i;
  7. //pack into box
  8. for (i=0;i<len1;++i){
  9. int v = s1[i];
  10. ++box[v];
  11. }
  12. //remove from box
  13. for (i=0;i<len2;++i){
  14. int v = s2[i];
  15. --box[v];
  16. }
  17. // is the box empty?
  18. for (i=0;i<len1;++i){
  19. int v = s1[i];
  20. if (box[v]>0) return 0;
  21. }
  22. return 1;
  23. }
  24. int main( int argc, const char *argv[])
  25. {
  26. if (argc!=3){
  27. printf( "%s s1 s2\n" ,argv[0]);
  28. return 1;
  29. }
  30. char *s1 = ( char *)argv[1];
  31. int l1 = strlen(s1);
  32. char *s2 = ( char *)argv[2];
  33. int l2 = strlen(s2);
  34. int isborther = brothstr(s1,l1,s2,l2);
  35. isborther? printf( "is brother\n" ,s1,s2):printf( "is not brother\n" ,s1,s2);
  36. return 0;
  37. }
#include <stdio.h> #include <string.h> int brothstr(const char *s1,int len1,const char *s2,int len2){ if(len1 != len2)return 0; int box[128] = {0}; int i; //pack into box for(i=0;i<len1;++i){ int v = s1[i]; ++box[v]; } //remove from box for(i=0;i<len2;++i){ int v = s2[i]; --box[v]; } // is the box empty? for(i=0;i<len1;++i){ int v = s1[i]; if(box[v]>0)return 0; } return 1; } int main(int argc, const char *argv[]) { if(argc!=3){ printf("%s s1 s2\n",argv[0]); return 1; } char *s1 = (char*)argv[1]; int l1 = strlen(s1); char *s2 = (char*)argv[2]; int l2 = strlen(s2); int isborther = brothstr(s1,l1,s2,l2); isborther? printf("is brother\n",s1,s2):printf("is not brother\n",s1,s2); return 0; }
132楼 eagleatustb 昨天 14:55发表 [回复]
第23题: 思路先建立数学模型,设3步的走 i 次,2步的走 j 次, 1步的走 k 次,上了3*i + 2*j + 1*k = n个台阶.总共走 i + j + k 次, 等于把n个台阶的长度先划分成 i + j + k 个段落, 然后分别填下i个3, j 个2, k个1.这样,当划分成 i + j + k 个段落时, 根据排列组合知识,所有填充方法有 (i + j + k )!/ ( i!*j!*k!) 种,程序中使用GetComb(i,j,k)函数计算此值. 在下一页贴上.
对于i, j, k的确定,我们可以用从大到小划分法, 先划分3的次数,再划分2的次数,剩下的都算做1的次数,具体程序中就是里面的i,j,两重循环.
  1. //23、人人笔试1:一个人上台阶可以一次上1个,2个,或者3个,问这个人上n层的台阶,总共有几种走法?
  2. //思路,建模分析得出结果是 所有 (i+j+k)!/(i!*j!*k!) 的和,其中i,j,k满足条件 3*i+2*j+k=n
  3. //以下解法暂不考虑数据过大的溢出问题
  4. int CItems::NStepFor123( int n)
  5. {
  6. int i=0;
  7. int j=0;
  8. int p;
  9. int k;
  10. int result=0;
  11. for ( i=0; i<=n/3; i++ )
  12. {
  13. p = n-i*3;
  14. for ( j=0; j<=p/2; j++ )
  15. {
  16. k = p -j*2;
  17. //求(i+j+k)!/(i!*j!*k!)
  18. result += GetComb(i,j,k);
  19. }
  20. }
  21. return result;
  22. }
//23、人人笔试1:一个人上台阶可以一次上1个,2个,或者3个,问这个人上n层的台阶,总共有几种走法? //思路,建模分析得出结果是 所有 (i+j+k)!/(i!*j!*k!) 的和,其中i,j,k满足条件 3*i+2*j+k=n //以下解法暂不考虑数据过大的溢出问题 int CItems::NStepFor123(int n) { int i=0; int j=0; int p; int k; int result=0; for ( i=0; i<=n/3; i++ ) { p = n-i*3; for ( j=0; j<=p/2; j++ ) { k = p -j*2; //求(i+j+k)!/(i!*j!*k!) result += GetComb(i,j,k); } } return result; }
Re: eagleatustb 昨天 14:56发表 [回复]
回复eagleatustb:续上:
  1. int CItems::GetComb( int i, int j, int k)
  2. {
  3. if ( i+j+k<0 || i<0 || j<0 || k<0)
  4. {
  5. return 0;
  6. }
  7. int den=1; //分母
  8. int mun=1; //分子
  9. int p; //临时变量
  10. for ( p = 1;p<=i+j+k; p++ ) //求分子
  11. {
  12. mun*=p;
  13. }
  14. if (i>0) //求分母中i!部分
  15. {
  16. for ( p = 1;p<=i; p++ )
  17. {
  18. den*=p;
  19. }
  20. }
  21. if (j>0) //求分母中i!j!部分
  22. {
  23. for ( p = 1;p<=j; p++ )
  24. {
  25. den*=p;
  26. }
  27. }
  28. if (k>0) //求分母总值
  29. {
  30. for ( p = 1;p<=k; p++ )
  31. {
  32. den*=p;
  33. }
  34. }
  35. return ( int )(mun/den); //可以用数学方法证明此除法得出的一定是整数
  36. }
int CItems::GetComb(int i,int j,int k) { if ( i+j+k<0 || i<0 || j<0 || k<0) { return 0; } int den=1;//分母 int mun=1;//分子 int p; //临时变量 for ( p = 1;p<=i+j+k; p++ )//求分子 { mun*=p; } if (i>0) //求分母中i!部分 { for ( p = 1;p<=i; p++ ) { den*=p; } } if (j>0)//求分母中i!j!部分 { for ( p = 1;p<=j; p++ ) { den*=p; } } if (k>0)//求分母总值 { for ( p = 1;p<=k; p++ ) { den*=p; } } return (int)(mun/den);//可以用数学方法证明此除法得出的一定是整数 }
Re: eagleatustb 昨天 15:05发表 [回复]
回复eagleatustb: CItems item;
int StepRes1;
for ( int i =1; i<20; i++ )
{
StepRes1 = item.NStepFor123(i);
printf("\n%d step for 1,2,3 method is %d",i,StepRes1);
}
结果如下:
1 step for 1,2,3 method is 1
2 step for 1,2,3 method is 2
3 step for 1,2,3 method is 4
4 step for 1,2,3 method is 7
5 step for 1,2,3 method is 13
6 step for 1,2,3 method is 24
7 step for 1,2,3 method is 44
8 step for 1,2,3 method is 81
9 step for 1,2,3 method is 149
10 step for 1,2,3 method is 274
11 step for 1,2,3 method is 504
12 step for 1,2,3 method is 927
13 step for 1,2,3 method is1705
14 step for 1,2,3 method is 3127
15 step for 1,2,3 method is 5691
16 step for 1,2,3 method is 10185
17 step for 1,2,3 method is 17695
18 step for 1,2,3 method is 29465
19 step for 1,2,3 method is 46435
131楼 zhao860216 昨天 14:49发表 [回复]
  1. document.write( "没一个会的!" )
document.write("没一个会的!")
130楼 onelikejava 昨天 13:06发表 [回复]
顶一个
129楼 eagleatustb 昨天 12:46发表 [回复]
21题
  1. //搜狗笔试题:一个长度为n的数组a[0],a[1],...,a[n-1]。现在更新数组的名个元素,即a[0]变为a[1]到a[n-1]的积,a[1]变为a[0]和a[2]到a[n-1]的积,...,a[n-1]为a[0]到a[n-2]的积。
  2. //程序要求:
  3. //要求具有线性复杂度。
  4. //不能使用除法运算符。
  5. #define MAX_ARRAY_SIZE 9
  6. void CItems::GetMultiplay()
  7. {
  8. int Array[MAX_ARRAY_SIZE]={1,2,3,4,5,6,7,8,9};
  9. int temp1[MAX_ARRAY_SIZE]={0};
  10. int temp2[MAX_ARRAY_SIZE]={0};
  11. temp1[0] = Array[0];
  12. temp2[MAX_ARRAY_SIZE-1] = Array[MAX_ARRAY_SIZE-1];
  13. for ( int j=1; j<MAX_ARRAY_SIZE; j++ )
  14. {
  15. temp1[j] = temp1[j-1]*Array[j];
  16. temp2[MAX_ARRAY_SIZE-1-j] = temp2[MAX_ARRAY_SIZE-j]*Array[MAX_ARRAY_SIZE-1-j];
  17. }
  18. Array[0] = temp2[1];
  19. Array[MAX_ARRAY_SIZE-1] = temp1[MAX_ARRAY_SIZE-2];
  20. for ( int i = 1; i<MAX_ARRAY_SIZE-1; i++ )
  21. {
  22. Array[i]=temp1[i-1]*temp2[i+1];
  23. }
  24. for ( int k = 0; k<MAX_ARRAY_SIZE; k++ )
  25. {
  26. printf( "Array[%d]=%d" ,i,Array[i]);
  27. }
  28. return ;
  29. }
//搜狗笔试题:一个长度为n的数组a[0],a[1],...,a[n-1]。现在更新数组的名个元素,即a[0]变为a[1]到a[n-1]的积,a[1]变为a[0]和a[2]到a[n-1]的积,...,a[n-1]为a[0]到a[n-2]的积。 //程序要求: //要求具有线性复杂度。 //不能使用除法运算符。 #define MAX_ARRAY_SIZE 9 void CItems::GetMultiplay() { int Array[MAX_ARRAY_SIZE]={1,2,3,4,5,6,7,8,9}; int temp1[MAX_ARRAY_SIZE]={0}; int temp2[MAX_ARRAY_SIZE]={0}; temp1[0] = Array[0]; temp2[MAX_ARRAY_SIZE-1] = Array[MAX_ARRAY_SIZE-1]; for ( int j=1; j<MAX_ARRAY_SIZE; j++ ) { temp1[j] = temp1[j-1]*Array[j]; temp2[MAX_ARRAY_SIZE-1-j] = temp2[MAX_ARRAY_SIZE-j]*Array[MAX_ARRAY_SIZE-1-j]; } Array[0] = temp2[1]; Array[MAX_ARRAY_SIZE-1] = temp1[MAX_ARRAY_SIZE-2]; for ( int i = 1; i<MAX_ARRAY_SIZE-1; i++ ) { Array[i]=temp1[i-1]*temp2[i+1]; } for ( int k = 0; k<MAX_ARRAY_SIZE; k++ ) { printf("Array[%d]=%d",i,Array[i]); } return ; }
Re: v_JULY_v 昨天 12:55发表 [回复]
回复eagleatustb:具体描述下你的思路吧。
128楼 neckbo 昨天 12:32发表 [回复]
mark下 留着以后看
127楼 IamStrayBird 昨天 11:55发表 [回复]
第13题,毒药的问题:
  1. int cacl( int mouse_count, int bottle_count)
  2. {
  3. int res = 0;
  4. for ( i = 1; i <= mouse_count; i++ ) {
  5. res += bottle_count/(1<<i);
  6. }
  7. return res;
  8. }
int cacl(int mouse_count, int bottle_count) { int res = 0; for ( i = 1; i <= mouse_count; i++ ) { res += bottle_count/(1<<i); } return res; }
126楼 IamStrayBird 昨天 11:50发表 [回复]
有点意思!
第二题,不知此解如何?
  1. int rand10()
  2. {
  3. int a, b;
  4. do {
  5. a = rand7();
  6. } while ( a > 5 );
  7. do {
  8. b = rand7();
  9. } while ( b > 2 );
  10. return a*2-(b-1);
  11. }
int rand10() { int a, b; do { a = rand7(); } while ( a > 5 ); do { b = rand7(); } while ( b > 2 ); return a*2-(b-1); }
125楼 pumpkinflower 昨天 11:35发表 [回复]
各种招聘进行中啊。
最近太多了,暂时不看了。
mark一下。
124楼 maxiaoyuan215 昨天 10:45发表 [回复]
很好的东西,我收藏了
123楼 alun0624 昨天 10:07发表 [回复]
求rand(10)这个简单做法是:
private int getRand10()
{
int a=rand(7);
int b=rand(7);
if((a+b)<11)
return a+b;
}
122楼 zzsyzxzm 昨天 08:04发表 [回复]
mark
121楼 tnt532185987 昨天 22:40发表 [回复]
望洋兴叹~啊
120楼 li215410389 昨天 21:13发表 [回复]
真是好东西啊
119楼 zhangjun840460920 昨天 20:39发表 [回复]
额。。。待我好好想想
118楼 csucdl 昨天 17:37发表 [回复]
[quote=csucdl]16题 不完整
  1. char const * MI(string const &amp...[/quote]
  2. 接着
  3. [code=cpp]
  4. char const * Add(string& x, string const & y)
  5. {
  6. char const * px = x.c_str();
  7. char const * py = y.c_str();
  8. char const * pxe = px + x.length();
  9. char const * pye = py + y.length();
  10. int carry = 0;
  11. list< char > r;
  12. for (--pxe, --pye; pxe >= px && pye >= py; --pxe, --pye)
  13. {
  14. int i = (*pxe - '0' ) + (*pye - '0' ) + carry;
  15. carry = i / 10;
  16. i %= 10;
  17. r.push_front(i + '0' );
  18. }
  19. for (; pxe >= px; --pxe)
  20. {
  21. int i = (*pxe - '0' ) + carry;
  22. carry = i / 10;
  23. i %= 10;
  24. r.push_front(i + '0' );
  25. }
  26. for (; pye >= py; --pye)
  27. {
  28. int i = (*pye - '0' ) + carry;
  29. carry = i / 10;
  30. i %= 10;
  31. r.push_front(i + '0' );
  32. }
  33. return x.assign(r.begin(), r.end() ).c_str();
  34. }
char const* MI(string const&amp...[/quote] 接着 [code=cpp] char const* Add(string& x, string const& y) { char const* px = x.c_str(); char const* py = y.c_str(); char const* pxe = px + x.length(); char const* pye = py + y.length(); int carry = 0; list<char> r; for (--pxe, --pye; pxe >= px && pye >= py; --pxe, --pye) { int i = (*pxe - '0') + (*pye - '0') + carry; carry = i / 10; i %= 10; r.push_front(i + '0'); } for (; pxe >= px; --pxe) { int i = (*pxe - '0') + carry; carry = i / 10; i %= 10; r.push_front(i + '0'); } for (; pye >= py; --pye) { int i = (*pye - '0') + carry; carry = i / 10; i %= 10; r.push_front(i + '0'); } return x.assign(r.begin(), r.end() ).c_str(); }
117楼 csucdl 昨天 17:36发表 [回复]
16题 不完整
  1. char const * MI(string const & x, int y, int z, string &s)
  2. {
  3. list< char > r;
  4. int carry = 0;
  5. for ( char const * p = x.c_str(), *pe = x.c_str() + x.length() - 1; pe >= p; --pe)
  6. {
  7. int i = (*pe - '0' ) * y + carry;
  8. carry = i / 10;
  9. i %= 10;
  10. r.push_front(i + '0' );
  11. }
  12. if (carry > 0)
  13. {
  14. r.push_front(carry + '0' );
  15. }
  16. for (; z > 0; --z)
  17. {
  18. r.push_back( '0' );
  19. }
  20. return s.assign(r.begin(), r.end() ).c_str();
  21. }
char const* MI(string const& x, int y, int z, string &s) { list<char> r; int carry = 0; for (char const* p = x.c_str(), *pe = x.c_str() + x.length() - 1; pe >= p; --pe) { int i = (*pe - '0') * y + carry; carry = i / 10; i %= 10; r.push_front(i + '0'); } if (carry > 0) { r.push_front(carry + '0'); } for (; z > 0; --z) { r.push_back('0'); } return s.assign(r.begin(), r.end() ).c_str(); }
116楼 xubo115 昨天 16:57发表 [回复]
第三题用了排序,那不是完全没难度了。。。
115楼 a13069730106 昨天 16:12发表 [回复]
三题为什么不用排序,把它们都排序,再比较
我用的都是java自带的排序

import java.util.Arrays;

public class Test{
public static void main(String[] args)
{
String str1="abc";
String str2="bca";
char[] arr1=str1.toCharArray();
char[] arr2=str2.toCharArray();
Arrays.sort(arr1);
Arrays.sort(arr2);
str1=new String(arr1);
str2=new String(arr2);
if(str1.equals(str2)){
System.out.println("是兄弟串");
}else{
System.out.println("不是兄弟串");
}

}
}
114楼 qindanloves 昨天 10:53发表 [回复]
做个记号,闲下来是看看
113楼 gmay 昨天 09:30发表 [回复]
第五题
  1. void PartitionSort( int q[], int n)
  2. {
  3. for ( int i=n-1, k=0; i>=0; i--)
  4. {
  5. if (q[i] >= 0)
  6. {
  7. if (k == 0) continue ;
  8. int t = q[i];
  9. memmove(&q[i], &q[i+1], k* sizeof ( int ));
  10. q[i+k] = t;
  11. }
  12. else
  13. k++;
  14. }
  15. }
void PartitionSort(int q[], int n) { for (int i=n-1, k=0; i>=0; i--) { if (q[i] >= 0) { if (k == 0) continue; int t = q[i]; memmove(&q[i], &q[i+1], k*sizeof(int)); q[i+k] = t; } else k++; } }
112楼 merryy 前天 08:34发表 [回复]
多年以后发现自己是门外汉
111楼 cheny_com 前天 01:11发表 [回复]
  1. int total = 0;
  2. for ( int i = 0; i < 10; i++)
  3. {
  4. total += Rand7();
  5. }
  6. return total / 7;
int total = 0; for (int i = 0; i < 10; i++) { total += Rand7(); } return total / 7;
110楼 alonecool 前天 22:11发表 [回复]
110楼的兄弟很NB啊!!
这个方法有点强盗逻辑,OTZ不过确实很巧妙……
109楼 biaohandexiaoheidou 前天 21:57发表 [回复]
第二题应该可以做:
  1. int rand7();
  2. int Random10()
  3. {
  4. int k, i;
  5. while (1)
  6. {
  7. int i = rand7();
  8. if (i < 6)
  9. {
  10. k = i;
  11. break ;
  12. }
  13. }
  14. while (1)
  15. {
  16. int i = rand7();
  17. if (i < 7)
  18. {
  19. if (i < 4)
  20. {
  21. k = k + 5;
  22. }
  23. break ;
  24. }
  25. }
  26. return k;
  27. }
int rand7(); int Random10() { int k, i; while(1) { int i = rand7(); if(i < 6) { k = i; break; } } while(1) { int i = rand7(); if(i < 7) { if(i < 4) { k = k + 5; } break; } } return k; }
108楼 bbw618 前天 17:25发表 [回复]
居然一题都不会,悲哀。
107楼 csucdl 前天 17:19发表 [回复]
第一题的递归算法
  1. int X( int iMonkey, int & iPerMonkey)
  2. {
  3. if (1 == iMonkey)
  4. {
  5. return 5 * iPerMonkey + 1;
  6. }
  7. int iLeft = X(iMonkey - 1, iPerMonkey);
  8. while (iLeft % 4)
  9. {
  10. iLeft = X(iMonkey - 1, ++iPerMonkey);
  11. }
  12. return 1 + 5 * iLeft / 4;
  13. }
int X(int iMonkey, int& iPerMonkey) { if (1 == iMonkey) { return 5 * iPerMonkey + 1; } int iLeft = X(iMonkey - 1, iPerMonkey); while (iLeft % 4) { iLeft = X(iMonkey - 1, ++iPerMonkey); } return 1 + 5 * iLeft / 4; }
106楼 hnxdyl 前天 16:26发表 [回复]
第一个是数学中一个数列的求和为题;定义sn为数列和(桃子数目),n为猴子数目。a1,a2。。。为数列的第一项和第二项。则sn=a1+n-1+(n-1)/n-(a1+a2+a3+。。。+an-1)/n+n。根据这个题目a1=(sn/n)+1,a2=(sn-a1)/n+1..那个sn的应该可以计算出来是关于n的函数(目前木有计算)
105楼 jerryh2008 前天 16:10发表 [回复]
实现如下:

import java.util.Set;
import java.util.TreeSet;

public class BrotherComparator {
Set<Character> set = null;

public BrotherComparator(String a) {
if (a == null)
set = null;
else {
set = new TreeSet<Character>();
for (int i = 0; i < a.length(); i++) {
set.add(a.charAt(i));
}
}
}

public Set<Character> getSet() {
return set;
}

public void setSet(Set<Character> set) {
this.set = set;
}

public boolean compareBrother(BrotherComparator brother) {
if (brother == null || brother.getSet() == null)
return false;

if (brother == this)
return true;

if (brother.getSet().toString().equals(set.toString()))
return true;
else
return false;
}

public static void main(String[] args) {
BrotherComparator a = new BrotherComparator("abd");
BrotherComparator b = new BrotherComparator("bda");
BrotherComparator c = null;
System.out.println(a.compareBrother(b));
}
}
最后输出结构true;
104楼 jerryh2008 前天 16:10发表 [回复]
第三题主要考虑数据结构问题,如果我们能找一个能存储字符并且能够自动排序每一个录入的字符,最后比较一下就可以了。
JAVA 符合这样的数据结构有TreeSet.
103楼 querdaizhi 前天 15:58发表 [回复]
第三题我是这样做的,代码挺简单的,效率不怎么样。
  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. char ch[100],ch1[100];
  6. int a[27],b[27];
  7. while (cin >> ch >> ch1)
  8. {
  9. memset(a,0,27* sizeof ( int ));
  10. memset(b,0,27* sizeof ( int ));
  11. int len1 = strlen(ch);
  12. int len2 = strlen(ch1);
  13. if (len1 != len2)
  14. {
  15. cout<< "不是兄弟字符串" <<endl;
  16. continue ;
  17. }
  18. for ( int i=0;i<len1;i++)
  19. {
  20. a[( int )ch[i] - 97]++;
  21. }
  22. for (i=0;i<len2;i++)
  23. {
  24. b[( int )ch1[i] - 97]++;
  25. }
  26. int flag=1;
  27. for (i=0;i<27;i++)
  28. {
  29. if (a[i] != b[i])
  30. {
  31. flag=0;
  32. break ;
  33. }
  34. }
  35. if (flag)
  36. {
  37. cout<< "是兄弟字符串" <<endl;
  38. }
  39. else
  40. {
  41. cout<< "不是兄弟字符串" <<endl;
  42. }
  43. }
  44. }
#include<iostream> using namespace std; int main() { char ch[100],ch1[100]; int a[27],b[27]; while(cin >> ch >> ch1) { memset(a,0,27*sizeof(int)); memset(b,0,27*sizeof(int)); int len1 = strlen(ch); int len2 = strlen(ch1); if(len1 != len2) { cout<<"不是兄弟字符串"<<endl; continue; } for(int i=0;i<len1;i++) { a[(int)ch[i] - 97]++; } for(i=0;i<len2;i++) { b[(int)ch1[i] - 97]++; } int flag=1; for(i=0;i<27;i++) { if(a[i] != b[i]) { flag=0; break; } } if(flag) { cout<<"是兄弟字符串"<<endl; } else { cout<<"不是兄弟字符串"<<endl; } } }
102楼 shawin 前天 15:48发表 [回复]
第五题睡觉的时候想了睡着了,找不到o(n),o(1)的方法,有点沮丧
101楼 ifineedhelp 前天 15:20发表 [回复]
引用“lovewhatilove”的评论: 回复erlangxiong:我看了下,怎么是无解呢?从后向前,找一个负数,...

如果只有一负数,并且在数组的最后一位。何解?
100楼 l1212s 前天 14:50发表 [回复]
  1. 如果两个字符串的字符一样,但是顺序不一样,被认为是兄弟字符串,问如何在迅速匹配兄弟字符串(如,bad和adb就是兄弟字符串)。
  2. #define TABLE_SIZE 256
  3. int main()
  4. {
  5. char string1[1000]= "bad" ;
  6. char string2[1000]= "adb" ;
  7. char *pstring1 ;
  8. char *pstring2 ;
  9. unsigned int hash_table[TABLE_SIZE] = {0};
  10. unsigned int index = 0;
  11. pstring1 = string1;
  12. pstring2 = string2;
  13. while (*pstring1){
  14. hash_table[*pstring1]+=1;
  15. printf( "%d\r\n" , *pstring1);
  16. pstring1++;
  17. }
  18. while (*pstring2){
  19. hash_table[*pstring2]-=1;
  20. printf( "%d\r\n" , *pstring2);
  21. pstring2++;
  22. }
  23. for (index = 0; index < TABLE_SIZE ; index++)
  24. if (hash_table[index]!=0)
  25. break ;
  26. if (index == TABLE_SIZE)
  27. printf( "%s == %s\r\n" , string1, string2);
  28. else
  29. printf( "%s != %s\r\n" , string1, string2);
  30. getchar();
  31. return 0;
  32. }
如果两个字符串的字符一样,但是顺序不一样,被认为是兄弟字符串,问如何在迅速匹配兄弟字符串(如,bad和adb就是兄弟字符串)。 #define TABLE_SIZE 256 int main() { char string1[1000]="bad"; char string2[1000]="adb"; char *pstring1 ; char *pstring2 ; unsigned int hash_table[TABLE_SIZE] = {0}; unsigned int index = 0; pstring1 = string1; pstring2 = string2; while(*pstring1){ hash_table[*pstring1]+=1; printf("%d\r\n", *pstring1); pstring1++; } while(*pstring2){ hash_table[*pstring2]-=1; printf("%d\r\n", *pstring2); pstring2++; } for(index = 0; index < TABLE_SIZE ; index++) if(hash_table[index]!=0) break; if(index == TABLE_SIZE) printf("%s == %s\r\n", string1, string2); else printf("%s != %s\r\n", string1, string2); getchar(); return 0; }
Re: v_JULY_v 前天 14:53发表 [回复]
回复l1212s:是否简单描述下你的思路?
99楼 jerryh2008 前天 14:50发表 [回复]
另外一种算法的:
public class Test {
/**
* 计算猴子分桃最少数,最后一只猴子不能吃桃,只能带走一个桃子。
* @param ave 最少基数
* @param count 猴子个数
* @param c 分桃次数,每次减1
* @return
*/
public static int split(int ave, int count, int c) {
int t = 1;
if (c != 1)
t = ave * (c) + 1;
System.out.println(c + "->" + t);
c++;
if (c == count + 1) {
return t;
} else {
return split(t, count, c);
}
}

public static void main(String args[]) throws Exception {
System.out.println("mix=" + split(1, 5, 1));
}
}
输入结果:
1->1
2->3
3->10
4->41
5->206
mix=206
Re: yhr619 前天 16:03发表 [回复]
回复jerryh2008:每个猴子还要拿走一堆呢
98楼 l1212s 前天 14:49发表 [回复]
如果两个字符串的字符一样,但是顺序不一样,被认为是兄弟字符串,问如何在迅速匹配兄弟字符串(如,bad和adb就是兄弟字符串)。

#define TABLE_SIZE 256

int main()
{
char string1[1000]="bad";
char string2[1000]="adb";
char *pstring1 ;
char *pstring2 ;
unsigned int hash_table[TABLE_SIZE] = {0};
unsigned int index = 0;

pstring1 = string1;
pstring2 = string2;

while(*pstring1){
hash_table[*pstring1]+=1;
printf("%d\r\n", *pstring1);
pstring1++;
}

while(*pstring2){
hash_table[*pstring2]-=1;
printf("%d\r\n", *pstring2);
pstring2++;
}


for(index = 0; index < TABLE_SIZE ; index++)
if(hash_table[index]!=0)
break;

if(index == TABLE_SIZE)
printf("%s == %s\r\n", string1, string2);
else
printf("%s != %s\r\n", string1, string2);

getchar();

return 0;
}
97楼 jerryh2008 前天 14:01发表 [回复]
第一题JAVA答案:
public class Test {
public static int split(int ave, int count, int c) {
int i = c;
int t = ave * (c++) + 1;
System.out.println(i + "->" + t);
if (c == 6) {
return t;
} else {
return split(t, count, c);
}
}

public static void main(String args[]) throws Exception {
System.out.println("mix=" + split(1, 5, 1));
}
}
肯定基数为1是最少数,既最后一只猴子吃掉一个,最后拿走一个。如果最后一只猴子不能吃,只能拿走那自己考虑了。
输入结果:
1->2
2->5
3->16
4->65
5->326
mix=326
96楼 DenielJean 前天 13:39发表 [回复]
第一题猴子分桃子,有五个猴子的时候桃子的数目为X=3125a+3121,其中a>=0。如果取最小,那么就是X(a=0)=3121了。具体计算方法见 http://blog.csdn.net/denieljean/article/details/6825777
95楼 Andy_NZ 前天 13:01发表 [回复]
收藏
94楼 cattlenzq 前天 12:16发表 [回复]
第三题,计算每个字符串的特征值,可以保存在int a[26];
下标0->25对应26个字母,数组的值为每个字符出现的次数,需要每个字符串遍历一遍才能得到特征值,插入特征值时就可以按大小排列成链表,到之后显示链表即可
93楼 cattlenzq 前天 12:12发表 [回复]
第二题如果不考虑性能的话,最简单的做法是
rand7做10次,然后累加以后对10取模后+1
92楼 cattlenzq 前天 12:00发表 [回复]
第一题
#include <stdio.h>

int a(int num, int split, int eat)
{
if (num == 1)
return num * split + eat;
else
return a(num - 1, split, eat) * split + eat;
}

int main()
{
printf("total: %d\n", a(5, 5, 1));
}
91楼 bill600 前天 11:27发表 [回复]
13题解答
任意一只喝一瓶
任意两只喝一瓶
任意三只喝一瓶
任意四只喝一瓶
任意五只喝一瓶
结果为
c5(1)+c5(2)+c5(3)+c5(4)+c5(5)=31
90楼 wboy181818 前天 11:11发表 [回复]
对哦,第二题应该是个概率统计的问题,将七分之一的概率变成十分之一的概率。
89楼 bill600 前天 11:05发表 [回复]
第二题的解答

在7进制下构造一个[0,1) 的随机函数,如下:
random()=(rand7()-1)/7+(rand7()-1)/7*7+(rand7()-1)/7*7*7+(rand7()-1)/7*7*7*7

有了[0,1) 的随机函数,剩下的都好办了
88楼 dengweikobe 前天 10:54发表 [回复]
变态的题目,等高手解答!
87楼 xubo115 前天 10:23发表 [回复]
楼主,你第二题方法的第二步貌似写的有问题?
我觉得应该是:
1.两次得到随机数 a1 a2 ;
2.如果 a1*7+a2<48 则 b=(a1*7+a2)/4-1 否则重复第一步;

非常感谢你的思路
86楼 eagleatustb 前天 09:38发表 [回复]
哥们,认真点,不是你想的这么简单的。。。 你的方法明显顺序变了,不理解的话,动手写出程序能说明问题。这题主要是复杂度无法到达所说的时间O(n),空间O(1). 所以说无解,并不是说不能实现顺序不变的分开正负数. 引用“lovewhatilove”的评论: 回复iicup:我看了下,怎么是无解呢?从后向前,找一个负数,往前找个正数...
Re: v_JULY_v 前天 11:03发表 [回复]
朋友,你有加上文中所公布的Algorithms群了么。希望,认识下你。
85楼 ppp7p 前天 09:35发表 [回复]
这是在考数学了,数学知识好的话,应该问题不大。
84楼 iicup 3天前 08:26发表 [回复]
第5题,CSDN上有一篇帖子,讨论的最后结果是“无解”
Re: lovewhatilove 前天 09:24发表 [回复]
回复iicup:我看了下,怎么是无解呢?从后向前,找一个负数,往前找个正数,交换位置,这样交换下去,最终交换完毕,结果自然就出来~正数,负数顺序自然不变的。
83楼 day_learn 3天前 23:12发表 [回复]
rand7()+rand()%4
Re: shihaojie1219 3天前 00:27发表 [回复]
回复day_learn:取1时只能是1+0
取2时可以是1+1、2+0
。。。
所以1-10不等概率。。。
82楼 x313695373 3天前 19:55发表 [回复]
回复sunjiankirk:你的不行吧??????相对位置要不变
81楼 csl19972000 3天前 19:52发表 [回复]
第一题: 从第五个开始往第一猴倒着推算.
第二题:
( rand7() + rand7() + rand7() + rand7() + rand7() + rand7() + rand7() + rand7() + rand7() + rand7() ) / 7
第三题: unsigned int count[24] ; 统计各个字符出现的次数,然后比较
第四题: IP 地址划分成两段数字,前一部分按照顺序排列,另外一部分按照hash表,在第二部分,最近查找的可以移到前面,没有经验,不知道是个什么规律。
第五题:依据快速排序的思想,排序一次就可以了,设置用来比较的 middle value = 0;
Re: shihaojie1219 3天前 00:20发表 [回复]
回复csl19972000:加10次 结果为10~70
10-70出现的机会必然是中间大,两头小,况且:
10、11、12、13除7取整为1
14、15、16、17、18、19、20除7取整为2
。。。。
1-10每个数机会不是1/10 。。。
Re: eagleatustb 前天 16:58发表 [回复]
回复csl19972000:我可以证明这种方法是概率分布不平均的,因为只用证明这种方法不正确,不需要详细的逻辑推理,使用枚举法得到答案:
1: 28250575
2: 28249980
3: 28248440
4: 28246570
5: 28245085
6: 28244524
7: 28245085
8: 28246570
9: 28248440
10:28249980
  1. int Array[7]={1,2,3,4,5,6,7};
  2. int Result[10]={0};
  3. for ( int a1 = 0;a1<7;a1++ ) //1
  4. { for ( int a2 = 0;a2<7;a2++) //2
  5. { for ( int a3 = 0;a3<7;a3++) //3
  6. { for ( int a4 = 0;a4<7;a4++) //4
  7. { for ( int a5 = 0;a5<7;a5++) //5
  8. { for ( int a6 = 0;a6<7;a6++) //6
  9. { for ( int a7 = 0;a7<7;a7++) //7
  10. { for ( int a8 = 0;a8<7;a8++) //8
  11. { for ( int a9 = 0;a9<7;a9++) //9
  12. { for ( int a10 = 0;a10<7;a10++) //10
  13. { int k = Array[a1]+Array[a2]+Array[a3]+Array[a4]+Array[a5]
  14. +Array[a6]+Array[a7]+Array[a8]+Array[a9]+Array[a10];
  15. k = k%10;
  16. Result[k]++;
  17. }}}}}}}}}}
  18. for ( int j=0; j<10;j++ )
  19. printf( "\nResult[%d] Count is :%d " ,j,Result[j]);
 int Array[7]={1,2,3,4,5,6,7}; int Result[10]={0}; for ( int a1 = 0;a1<7;a1++ )//1 {for (int a2 = 0;a2<7;a2++)//2 {for (int a3 = 0;a3<7;a3++)//3 { for (int a4 = 0;a4<7;a4++)//4 {for (int a5 = 0;a5<7;a5++)//5 {for (int a6 = 0;a6<7;a6++)//6 {for (int a7 = 0;a7<7;a7++)//7 {for (int a8 = 0;a8<7;a8++)//8 {for (int a9 = 0;a9<7;a9++)//9 {for (int a10 = 0;a10<7;a10++)//10 {int k = Array[a1]+Array[a2]+Array[a3]+Array[a4]+Array[a5] +Array[a6]+Array[a7]+Array[a8]+Array[a9]+Array[a10]; k = k%10; Result[k]++; }}}}}}}}}} for ( int j=0; j<10;j++ ) printf("\nResult[%d] Count is :%d ",j,Result[j]);

而楼主发的那种方法显然不太稳定,依赖于rand7()产生两数积少于40,目前我也没找到更好的解决方法。
80楼 x313695373 3天前 19:38发表 [回复]
第5题,思路是一正一反,每次循环会设置好一个正数和一个负数的位置。
  1. //return:negative count
  2. int xsort( int *data, int size)
  3. {
  4. int neg_num = 0;
  5. int pos_p, neg_p;
  6. int i, j;
  7. for (i = 0; i < size; i++) //总的负数个数
  8. if (data[i] < 0)
  9. neg_num++;
  10. int pos_num = 0;
  11. for (i = 0; i < neg_num; i++)
  12. if (data[i] >=0)
  13. pos_num++;
  14. i = 0, j = size -1;
  15. pos_p = neg_num;
  16. neg_p = neg_num - 1;
  17. while (pos_num > 0){
  18. while (data[i] < 0) i++; //找正数
  19. int tmp = data[i];
  20. int k = i;
  21. while (k++ < neg_p)data[k-1] = data[k]; //腾出了负数的位置
  22. while (data[j] >=0)j--; //找负数
  23. data[neg_p--] = data[j]; //负数搁进去
  24. k = j;
  25. while (k-- > pos_p)data[k+1] = data[k]; //腾出了正数的位置
  26. data[pos_p++] = tmp; //正数搁进去
  27. pos_num--;
  28. }
  29. return neg_num;
  30. }
//return:negative count int xsort(int *data, int size) { int neg_num = 0; int pos_p, neg_p; int i, j; for(i = 0; i < size; i++)//总的负数个数 if(data[i] < 0) neg_num++; int pos_num = 0; for(i = 0; i < neg_num; i++) if(data[i] >=0) pos_num++; i = 0, j = size -1; pos_p = neg_num; neg_p = neg_num - 1; while(pos_num > 0){ while(data[i] < 0) i++;//找正数 int tmp = data[i]; int k = i; while(k++ < neg_p)data[k-1] = data[k];//腾出了负数的位置 while(data[j] >=0)j--;//找负数 data[neg_p--] = data[j];//负数搁进去 k = j; while(k-- > pos_p)data[k+1] = data[k];//腾出了正数的位置 data[pos_p++] = tmp;//正数搁进去 pos_num--; } return neg_num; }
Re: erlangxiong 3天前 21:45发表 [回复]
回复x313695373:恩 结果可以达到要求;
时间复杂度我觉得是
O(N) //求负数个数
+ O(N) //求pos_num
+ k*( O(N)+O(N)+O(N)+O(N)) //pos_num次大循环中的四次遍历。
= k*O(N);
k为负数的个数前面部分的正数个数pos_num 。
按说k为常数 故 时间复杂度也可以达到要求。
Re: x313695373 前天 16:54发表 [回复]
回复x313695373:sorry,这个不对,达不到O(N)的要求
79楼 sadfishsc 3天前 19:24发表 [回复]
第二题:
  1. int n = 0;
  2. int m = 0;
  3. int p = -1;
  4. while (n == 0) {
  5. m = rand7();
  6. if (m == 6) {
  7. p = 0
  8. }
  9. else if (m == 7) {
  10. p = 5;
  11. }
  12. else {
  13. if (p >= 0) {
  14. n = m + p;
  15. }
  16. }
  17. }
  18. return n;
int n = 0; int m = 0; int p = -1; while (n == 0) { m = rand7(); if (m == 6) { p = 0 } else if (m == 7) { p = 5; } else { if (p >= 0) { n = m + p; } } } return n;
Re: xubo115 前天 10:00发表 [回复]
回复sadfishsc:这个好高深- -
78楼 wboy181818 3天前 18:38发表 [回复]
第二题 rand7()+ rand7()再判断个位
77楼 zhouqianghust 3天前 17:11发表 [回复]
第一题:
#include <iostream>
using namespace std;

bool test(int n)
{
for (int j = 0; j < 5; j++)
{
if ((n - 1)%5 != 0)
{
return false;
}
n = (n - 1)/5 * 4;
}
return true;
}

void main()
{
for (int i = 10; i < 10000; i++)
{
if(test(i))
cout << i << " ";
}
cout << endl;
}
76楼 dryZeng 3天前 17:00发表 [回复]
return rand7() + ( rand7() - 1 ) / 2;
75楼 pilihou 3天前 16:37发表 [回复]
引用“xubo115”的评论: 第二题有人解决掉吗??
(7-rand7)/(7-1)*(10-1)+1这样应该可以
这是反求0到1随机数,再求1到10随机
74楼 eagleatustb 3天前 16:36发表 [回复]
已经有很多人出答案了啊,10个rand7()相加整除10啊。
引用“xubo115”的评论: 第二题有人解决掉吗??
Re: xubo115 3天前 16:57发表 [回复]
回复eagleatustb:10个rand7相加,模10取余,能得到10个结果,每个结果都来自7种可能,但是怎么验证它们总的概率是相等的呢
73楼 xubo115 3天前 16:12发表 [回复]
第二题有人解决掉吗??
72楼 tao1702007 3天前 16:08发表 [回复]
猴子分桃,这样行不?
  1. private void aa()
  2. {
  3. for ( int n = 1; n <= 1000000; n++)
  4. {
  5. if (a1(n))
  6. {
  7. MessageBox.Show(n.ToString());
  8. break ;
  9. }
  10. }
  11. }
  12. private bool a1( int n)
  13. {
  14. //第一次
  15. if ((n-1)%5==0)
  16. {
  17. n = ((n - 1) / 5) * 4; //第一次结余数
  18. if ((n - 1) % 5 == 0)
  19. {
  20. n = ((n - 1) / 5) * 4; //第二次结余数
  21. if ((n - 1) % 5 == 0)
  22. {
  23. n = ((n - 1) / 5) * 4; //第三次结余数
  24. if ((n - 1) % 5 == 0)
  25. {
  26. n = ((n - 1) / 5) * 4; //第四次结余数
  27. if ((n - 1) % 5 == 0)
  28. {
  29. n = ((n - 1) / 5) * 4; //第五次结余数
  30. return true ;
  31. }
  32. }
  33. }
  34. }
  35. }
private void aa() { for (int n = 1; n <= 1000000; n++) { if (a1(n)) { MessageBox.Show(n.ToString()); break; } } } private bool a1(int n) { //第一次 if ((n-1)%5==0) { n = ((n - 1) / 5) * 4;//第一次结余数 if ((n - 1) % 5 == 0) { n = ((n - 1) / 5) * 4;//第二次结余数 if ((n - 1) % 5 == 0) { n = ((n - 1) / 5) * 4;//第三次结余数 if ((n - 1) % 5 == 0) { n = ((n - 1) / 5) * 4;//第四次结余数 if ((n - 1) % 5 == 0) { n = ((n - 1) / 5) * 4;//第五次结余数 return true; } } } } }
71楼 xxcoopjiwhu 3天前 15:46发表 [回复]
哈哈,这么难啊
70楼 wangziyang_shuaige 3天前 15:42发表 [回复]
第一题,我上次在看一个创新工厂的时候看过这个题,闲了的时候也看了看,最初用各种假设,不过后来觉得这tmd不就一道高中还是初中数学中学的那个求值嘛,然后用数学的方法解释一下:设剩下的鱼的条数为x条,一共有y条鱼得出以下:
5x/4+1)5/4+1)5/4+1)5/4+1)5/4+1=y
当x>=1时,即可求出y的值。
没有去算这个值是多少,如觉得此方法不妥,请求指导。
69楼 eagleatustb 3天前 15:13发表 [回复]
也是枚举啊。。。
引用“xubo115”的评论: 第一题:3121,代码如下,暂时木有参考其他人,继续下面的题
[code=java]
public ...
Re: xubo115 3天前 15:32发表 [回复]
回复eagleatustb:题目一看,最快只能想到这个办法了,我正在看高手们的解答- -
Re: xubo115 3天前 16:01发表 [回复]
回复eagleatustb:第二题你做出来没?
68楼 xubo115 3天前 14:35发表 [回复]
第一题:3121,代码如下,暂时木有参考其他人,继续下面的题
  1. public class peach {
  2. public static void main(String []args){
  3. int i,j;
  4. int n= 6 ;
  5. for (;;){
  6. i=n;
  7. for (j= 1 ;j<= 6 ;j++){
  8. if ((i- 1 )% 5 == 0 )
  9. i= (i- 1 )* 4 / 5 ;
  10. else break ;
  11. }
  12. if (j == 6 )
  13. break ;
  14. n=n+ 5 ;
  15. }
  16. System.out.println( "the min number is " +n);
  17. }
  18. }
public class peach { public static void main(String []args){ int i,j; int n=6; for(;;){ i=n; for(j=1;j<=6;j++){ if ((i-1)%5 == 0) i= (i-1)*4/5; else break; } if (j == 6) break; n=n+5; } System.out.println("the min number is "+n); } }
67楼 eagleatustb 3天前 14:17发表 [回复]
第三题:如果两个字符串的字符一样,但是顺序不一样,被认为是兄弟字符串,问如何在迅速匹配兄弟字符串(如,bad和adb就是兄弟字符串)。
题目没有说明单个字符串内有没有重复,两个串重复个数要不要一致,我现在按重复个数也需要一致处理。
时间复杂度:O(n); n为字符串长度,再次遍历128次是常数,少于O(n),忽略。
空间复杂度:O(1); 固定为128个桶排序原理需要的空间。其他临时变量忽略不计
  1. bool CItems::CheckBrotherString( char *left, char *right)
  2. {
  3. //把键盘128个字符列举,使用桶排序相关原理实现
  4. char keys[128];
  5. for ( int i = 0; i<128; i++ )
  6. {
  7. keys[i]=0;
  8. }
  9. //遍历第一个字符串,记录字符个数
  10. while ( *left!= '\0' )
  11. {
  12. keys[*left++]++;
  13. }
  14. //遍历第二个字符串,记录字符个数
  15. while ( *right!= '\0' )
  16. {
  17. keys[*right++]--;
  18. }
  19. for ( int i = 0; i<128; i++ )
  20. {
  21. if ( keys[i]!=0)
  22. {
  23. return false ;
  24. }
  25. }
  26. return true ;
  27. }
bool CItems::CheckBrotherString(char *left,char *right) { //把键盘128个字符列举,使用桶排序相关原理实现 char keys[128]; for ( int i = 0; i<128; i++ ) { keys[i]=0; } //遍历第一个字符串,记录字符个数 while ( *left!='\0' ) { keys[*left++]++; } //遍历第二个字符串,记录字符个数 while ( *right!='\0' ) { keys[*right++]--; } for ( int i = 0; i<128; i++ ) { if ( keys[i]!=0) { return false; } } return true; }
66楼 eagleatustb 3天前 13:43发表 [回复]
第一题题意考查的不是会不会枚举数字判断,是运筹学里的整数规划问题!大家要明确题目考查的知识点。使用好知识以后这题计算复杂度是O(n)(n是猴子数目),即使来10,1000个猴子,也一样能算;
注:数字溢出先不考虑
但如果用枚举法,算法复杂度?先不用逻辑判断,单单5->3121;粗略算了一下,起码是O(n^3)!
65楼 eagleatustb 3天前 13:18发表 [回复]
  1. case 2:
  2. //m*k%4 need to equal 2
  3. switch ( m%4 )
  4. {
  5. case 1:
  6. k = 2;
  7. break ;
  8. case 2:
  9. k = 1;
  10. break ;
  11. case 3:
  12. printf( "ERROR!" );
  13. break ;
  14. default :
  15. printf( "ERROR!" );
  16. break ;
  17. }
  18. break ;
  19. case 3:
  20. //m*k%4 need to equal 1
  21. switch ( m%4 )
  22. {
  23. case 1:
  24. k = 1;
  25. break ;
  26. case 2:
  27. printf( "ERROR!" );
  28. break ;
  29. case 3:
  30. k = 7;
  31. break ;
  32. default :
  33. printf( "ERROR!" );
  34. break ;
  35. }
  36. break ;
  37. default :
  38. break ;
  39. }
  40. return k;
  41. }
 case 2: //m*k%4 need to equal 2 switch ( m%4 ) { case 1: k = 2; break; case 2: k = 1; break; case 3: printf("ERROR!"); break; default: printf("ERROR!"); break; } break; case 3: //m*k%4 need to equal 1 switch ( m%4 ) { case 1: k = 1; break; case 2: printf("ERROR!"); break; case 3: k = 7; break; default: printf("ERROR!"); break; } break; default: break; } return k; }
64楼 eagleatustb 3天前 13:17发表 [回复]
  1. int CItems::GetKValue( int y, int m)
  2. {
  3. int k=-1;
  4. //let x = y+m*k;
  5. //search k st. x is integer
  6. //y%5=1;make (m*k)%4 = 3
  7. switch ( y%4 )
  8. {
  9. case 0:
  10. //m*k%4 need to equal 4
  11. switch ( m%4 )
  12. {
  13. case 1:
  14. case 3:
  15. k = 4;
  16. break ;
  17. case 2:
  18. k = 2;
  19. break ;
  20. default :
  21. printf( "ERROR!" );
  22. break ;
  23. }
  24. break ;
  25. case 1:
  26. //(m*k)%4 need to equal 3
  27. switch ( m%4 )
  28. {
  29. case 1:
  30. k = 3;
  31. break ;
  32. case 2:
  33. printf( "ERROR!" );
  34. break ;
  35. case 3:
  36. k = 1;
  37. break ;
  38. default :
  39. printf( "ERROR!" );
  40. break ;
  41. }
  42. break ;
int CItems::GetKValue(int y,int m) { int k=-1; //let x = y+m*k; //search k st. x is integer //y%5=1;make (m*k)%4 = 3 switch ( y%4 ) { case 0: //m*k%4 need to equal 4 switch ( m%4 ) { case 1: case 3: k = 4; break; case 2: k = 2; break; default: printf("ERROR!"); break; } break; case 1: //(m*k)%4 need to equal 3 switch ( m%4 ) { case 1: k = 3; break; case 2: printf("ERROR!"); break; case 3: k = 1; break; default: printf("ERROR!"); break; } break;
63楼 eagleatustb 3天前 13:15发表 [回复]
第一题:五只猴子分桃。半夜,第一只猴子先起来,它把桃分成了相等的五堆,多出一只。于是,它吃掉了一个,拿走了一堆; 第二只猴子起来一看,只有四堆桃。于是把四堆合在一起,分成相等的五堆,又多出一个。于是,它也吃掉了一个,拿走了一堆;......其他几只猴子也都是 这样分的。问:这堆桃至少有多少个?(朋友说,这是小学奥数题)。
正确答案
  1. void CItems::MonkeyAndPeachs()
  2. {
  3. //y0-1 = 5*y1/4;
  4. //y1-1 = 5*y2/4;
  5. //y2-1 = 5*y3/4;
  6. //y3-1 = 5*y4/4;
  7. //y4-1 = 5*y5/4;
  8. int y = 0;
  9. //int x = 0;
  10. int m = 1;
  11. int k = 0;
  12. int i;
  13. for ( i =0;i<5;i++ )
  14. {
  15. if ( (k = GetKValue(y,m))<0 )
  16. {
  17. printf( "ERROR!" );
  18. return ;
  19. }
  20. //x = y+m*k;
  21. //y = x*5/4+1;
  22. y = (y+m*k)*5/4+1;
  23. m *=5;
  24. printf( ",%d:%d \n" ,i,y);
  25. }
  26. printf( "The result is %d" ,y);
  27. return ;
  28. }
void CItems::MonkeyAndPeachs() { //y0-1 = 5*y1/4; //y1-1 = 5*y2/4; //y2-1 = 5*y3/4; //y3-1 = 5*y4/4; //y4-1 = 5*y5/4; int y = 0; //int x = 0; int m = 1; int k = 0; int i; for ( i =0;i<5;i++ ) { if ( (k = GetKValue(y,m))<0 ) { printf("ERROR!"); return ; } //x = y+m*k; //y = x*5/4+1; y = (y+m*k)*5/4+1; m *=5; printf(",%d:%d \n",i,y); } printf("The result is %d",y); return ; }
62楼 qiludadi1987 3天前 11:41发表 [回复]
mark 一下 抽时间研究一下
61楼 ywch520 3天前 11:35发表 [回复]
1只老鼠 可以最多判断2瓶毒药 2^1
2只最多判断 4瓶毒药 2^2
3只 8 2^3
1 喝 1357
2 喝 2356
3 喝 4567

如果1 死 2 3 活 则 第1瓶有毒 二进制 也就是 001
如果2 死 1 3 活 则 第2瓶有毒 二进制 也就是 010
如果1 2 死 3 活 则 第3瓶有毒 二进制 也就是 011
如果3 死 1 2 活 则 第4瓶有毒 二进制 也就是 100
如果1 3 死 2 活 则 第5瓶有毒 二进制 也就是 101
如果2 3 死 1 活 则 第6瓶有毒 二进制 也就是 110
如果1 2 3 全死 则 第7瓶有毒 二进制 也就是 111
如果1 2 3 全活 则 第8瓶有毒 二进制 也就是1000
所以5只老鼠可以测2的5次方也就是32瓶
Re: rojay17 3天前 15:46发表 [回复]
回复ywch520:你是对的
60楼 huoguofeng 3天前 11:32发表 [回复]
好东东. 淘便宜 www.itaobb.com
淘宝打折网 www.xflian.com
59楼 WindYou 3天前 10:39发表 [回复]
rand10的问题,循环10次就够了,多了也没有用,少了概率分布不均匀。
int rand10() {
int value = 0;

for(int i = 0; i < 10; i++) {
value += rand7();
}

return value % 10;
}
58楼 tairikun01 3天前 10:25发表 [回复]
第2题最简单,10个rand7()相加,除以7并取整应该就可以了。
Re: googya 3天前 13:39发表 [回复]
回复tairikun01:估计不行,直接除的话有些数字覆盖不到的
Re: lovewhatilove 前天 09:34发表 [回复]
回复tairikun01:玩骰子,扔到8点,跟扔到2,12点概率一样吗?想清楚在回答~
1,1概率是1/36,3,5,35,44,6,2,2,6,你自己对比概率多少吧
57楼 tangjianping156 3天前 09:24发表 [回复]
竟然能用程序啊,那就好办多了,我还在用笔算呢,浪费时间啊
56楼 dzb19891120 3天前 09:11发表 [回复]
桃子问题:
#include<iostream.h>

void main()
{
int peach_number; //存储分之前的桃子个数
int peach_number1; //存储第1只猴子操作后剩下的桃子个数
int peach_number2; //存储第2只猴子操作后剩下的桃子个数
int peach_number3; //存储第3只猴子操作后剩下的桃子个数
int peach_number4; //存储第4只猴子操作后剩下的桃子个数

for( peach_number=6;peach_number>=6;peach_number++)
{
if((peach_number-1)%5==0)
{
peach_number1=(peach_number-1)*4/5;
if((peach_number1-1)%5==0)
{
peach_number2=(peach_number1-1)*4/5;
if((peach_number2-1)%5==0)
{
peach_number3=(peach_number2-1)*4/5;
if((peach_number3-1)%5==0)
{
peach_number4=(peach_number3-1)*4/5;
if((peach_number4-1)%5==0) //第5只猴子操作后,满足要求就退出循环
break;

}
}
}
}
}
cout<<"桃子至少含有:"<<peach_number<<endl;
}
55楼 zhaxun 4天前 02:21发表 [回复]
第二题:
int rand10()
{
int nResult=0;

while(true)
{
nResult=rand7();
if(nResult<=5)
break;
}
while(true)
{
int n = rand7();
if (n==1)
continue;
else if(n>4)
nResult*=2;
else
nResult=nResult*2-1;
break;
}
return nResult ;
}
我能想到的效率比较高、随机比较平均的算法,用加法和乘法的好像都有问题,因为数值分区间的概率是有问题的
54楼 love_t 4天前 00:05发表 [回复]
13题:

无数瓶无色液体,只有一瓶是毒药
喝了无色液体,五分钟后才会看到结果。
现在五只老鼠,五分钟的时间,问能检测多少瓶液体
1、五只小白鼠分别喝了5瓶无色液体,五分钟过后,其中一只死亡,那么可以确定全部液体,只有一瓶毒药,那么就全部分开来。
2、分别喝了在5分钟后均未死亡,那么只能确定5瓶蒸馏水。

PS:给定的条件是五只老鼠,五分钟的时间,每只老鼠喝了毒药五分钟后才会死亡。
Re: chenxiaohong3905 3天前 09:28发表 [回复]
回复love_t:为何不考虑,把其中的2瓶或者三瓶或者4瓶等组合起来再给老鼠吃呢?
这样至少可以检查大于5瓶的个数。
至少可以检测8瓶。如果要检测到10瓶的,有一定的概率。
一下方法可以一次性检测10瓶。
把10瓶毒药分为4组,前三组各三瓶,最后1组1瓶。
只检测前面三组。
假定三个组分别为A,B,C。
1. 把A,B,C三组中的液体混合,分别给三只老鼠喝。
分别为测试用例 a,b,c
2. 分别从A,B,C组中各取1只液体,混合,给第四只老鼠吃。为测试用例 d
3.分别在从A,B,C组中各取一次液体(第二部取过的,不能在取),混合,给第五只老鼠吃。为测试用例e

这样,不过毒药在那瓶液体都可以在5分钟中一次性得到液体在拿一瓶。
如果 abcde都活着,说明毒药是那瓶没有参加测试的。
如果abcde只有一个死了,说明毒液在在吃参与混合测试一次的那瓶液体中。虽然有三瓶液体只混合了一次测试,但是从死的那只测试编号可以知道是那个组。
如果abcde死了2只,那么交叉也可以得出那瓶是毒液。
53楼 Jackie_GP 4天前 22:55发表 [回复]
都是人才
52楼 lhltolerate 4天前 22:32发表 [回复]
猴子分桃的答案,能够连续5次(每次递增N)除4余数为0,并除5余1,除到第5次时,就是最终数了。
51楼 wang_wen_feng 4天前 22:04发表 [回复]
哈,桃子问题我答案算出来了,但是方法好复杂,看楼上的解答,恍然大悟,简洁明了,正是优秀算法的实现啊,什么时候我才能达到25楼的水平呢
Re: eagleatustb 前天 09:46发表 [回复]
大家总是爱说反话。。。回复wang_wen_feng:
50楼 x313695373 4天前 21:54发表 [回复]
  1. //需要事先知道字符集,假定为26个字母吧
  2. bool matchbrotherstr( char * str1, char * str2)
  3. {
  4. int s1[26] = {0}, s2[26] = {0};
  5. char *p;
  6. for (p = str1; *p != NULL;p++)
  7. s1[*p - 'a' ]++;
  8. for (p = str2; *p != NULL;p++)
  9. s2[*p - 'a' ]++;
  10. for ( int i = 0; i < 26; i++){
  11. if (s1[i] == s2[i])
  12. continue ;
  13. else
  14. return false ;
  15. }
  16. return true ;
  17. }
//需要事先知道字符集,假定为26个字母吧 bool matchbrotherstr(char* str1, char* str2) { int s1[26] = {0}, s2[26] = {0}; char *p; for(p = str1; *p != NULL;p++) s1[*p -'a']++; for(p = str2; *p != NULL;p++) s2[*p -'a']++; for(int i = 0; i < 26; i++){ if(s1[i] == s2[i]) continue; else return false; } return true; }
Re: bsglz 4天前 22:22发表 [回复]
回复x313695373:这个方法和前面的7*(random7()-1) + random7() 方法都是概率均等的,但是都需要对随机数进行有效性判断,如果运气足够差,那么永远也返回不了,有没有更好的方法呢
49楼 x313695373 4天前 21:43发表 [回复]
这个应该是随机的,实在想不到更好的办法了,
其实这题挺难的,应为要实现真正的随机,我想大多数人一开始想的方法都不是随机分布的
  1. int rand7()
  2. {
  3. return rand()%7 + 1;
  4. }
  5. int rand10()
  6. {
  7. int tmp, mid;
  8. do {
  9. mid = rand7();
  10. } while (mid == 4);
  11. //50%概率
  12. if (mid < 4){ //return 1-5
  13. do {
  14. tmp = rand7();
  15. } while (tmp == 1 || tmp == 7);
  16. return tmp - 1;
  17. } else { //return 6-10
  18. do {
  19. tmp = rand7();
  20. } while (tmp == 1 || tmp == 7);
  21. return tmp + 4;
  22. }
  23. }
int rand7() { return rand()%7 + 1; } int rand10() { int tmp, mid; do{ mid = rand7(); }while(mid == 4); //50%概率 if(mid < 4){//return 1-5 do{ tmp = rand7(); }while(tmp == 1 || tmp == 7); return tmp - 1; }else{//return 6-10 do{ tmp = rand7(); }while(tmp == 1 || tmp == 7); return tmp + 4; } }
48楼 nwpulei 4天前 21:28发表 [回复]
11题想了一个O(N^2)的算法(N为集合中的元素总数)
设有n个集合(集合用队列表示)
for(i =0; i < n;++i)
{
取出集合i中的一个元素x并依次和集合i+1到集合n-1比较,
如果x在后面的集合中,则后面的集合与当前集合合并。
合并后n减1.
}
47楼 x313695373 4天前 20:18发表 [回复]
第一题:答案为3121;
  1. int _tmain( int argc, _TCHAR* argv[])
  2. {
  3. int result = 0;
  4. while ( true ){
  5. int a[6];
  6. a[5] = result*4;
  7. int i;
  8. for (i = 4; i >=0; i--){
  9. if (a[i+1]%4 == 0){
  10. a[i] = a[i+1]*5/4 + 1;
  11. continue ;
  12. }
  13. break ;
  14. }
  15. if (i == -1){
  16. printf( "%d" , a[0]);
  17. break ;
  18. }
  19. else
  20. result++;
  21. }
  22. return 0;
  23. }
int _tmain(int argc, _TCHAR* argv[]) { int result = 0; while(true){ int a[6]; a[5] = result*4; int i; for(i = 4; i >=0; i--){ if(a[i+1]%4 == 0){ a[i] = a[i+1]*5/4 + 1; continue; } break; } if(i == -1){ printf("%d", a[0]); break; } else result++; } return 0; }
46楼 bsglz 4天前 19:51发表 [回复]
第二题:
function rand10()
{
int a = rand7();
int b = rand7();
int c = rand7();
int m = a+b+c;//值是3到21
int n = m-1;//值是2到20
return n/2;
}
Re: nwpulei 4天前 21:21发表 [回复]
回复bsglz:刚开始觉得挺好的,后来……
3=1+1+1
4=1+1+2=1+2+1=2+1+1 4的概率是3的概率的三倍
5=1+1+3=……
目前觉得
引用“wwq3073135”的评论: 2、while(1){
x=7*(random7()-1) + random7() ;
if(x...[/quote]
的方法比较好
解释见
[quote=chaoyue1216]明白了,确实是 7*(random7()-1) + random7() 生成的数在1到49间均匀分面...
45楼 blogyuantg 4天前 18:58发表 [回复]
搞这么难得题目,不知道给开多少工资?哥还是悠着点
44楼 eagleatustb 4天前 14:13发表 [回复]
第六题:淘宝面试题:有一个一亿节点的树,现在已知两个点,找这两个点的共同的祖先。

题目没有说明是使用什么方式存储什么样的树,我只以最简单的完全二叉树的方式去计算。
如果不是二叉树又另当别论
  1. //如果二叉树使用数组顺序存储结构,第一个节点下标是x,第二个节点下标是y;
  2. //第0个节点不使用,1为根节点,算法如下
  3. int x =10;
  4. int y =100;
  5. while (1)
  6. {
  7. if (x==y)
  8. {
  9. break ;
  10. }
  11. x>y?x/=2:y/=2;
  12. }
  13. printf( "The parent is %d" ,x);
 //如果二叉树使用数组顺序存储结构,第一个节点下标是x,第二个节点下标是y; //第0个节点不使用,1为根节点,算法如下 int x =10; int y =100; while(1) { if (x==y) { break; } x>y?x/=2:y/=2; } printf("The parent is %d",x);
43楼 eagleatustb 4天前 14:08发表 [回复]
第五题:
  1. int Array[10] = { -1,2,-3,4,-5,6,-7,8,-9,10 };
  2. int index_front = 0;
  3. int temp;
  4. int i;
  5. int j;
  6. for ( i = 0; i<10; i++ )
  7. {
  8. if (Array[i]<0)
  9. {
  10. temp = Array[i];
  11. for ( j = i;j>index_front; j--)
  12. {
  13. Array[j] = Array[j-1];
  14. }
  15. Array[index_front] = temp;
  16. index_front++;
  17. }
  18. }
  19. for ( i = 0; i<10; i++ )
  20. {
  21. printf( ", %d" ,Array[i]);
  22. }
 int Array[10] = { -1,2,-3,4,-5,6,-7,8,-9,10 }; int index_front = 0; int temp; int i; int j; for ( i = 0; i<10; i++ ) { if (Array[i]<0) { temp = Array[i]; for ( j = i;j>index_front; j--) { Array[j] = Array[j-1]; } Array[index_front] = temp; index_front++; } } for ( i = 0; i<10; i++ ) { printf(", %d",Array[i]); }
Re: nwpulei 4天前 21:16发表 [回复]
回复eagleatustb:时间复杂度是O(N)
Re: sunjiankirk 4天前 21:48发表 [回复]
回复eagleatustb:你这个算法不是O(N)吧?
42楼 hellosijian 4天前 14:00发表 [回复]
第一题
const int monkey = 5;
bool text_last_take(int n)
{
for(int i = 0 ; i < monkey - 1 ; i ++)
{
if((n*5+1)%4 == 0)
{
n =(n*5+1)/4;
continue;
}
return false;
}
return true;
}
int total(void)
{
int last_get = 0 ;

while(! text_last_take(++last_get))
{
if(last_get>1000) return 0;
}
printf("%d\n",last_get);
for(int i = 0 ; i < monkey-1;i++)
{
last_get = (last_get*5+1)/4;
}
return last_get*5+1;
}
int main(int argc, char* argv[])
{
printf("%d\n",total());
return 0;
}
不知道是不是,我是枚举出最后一个猴子拿走的的那一份个数然后回溯上去,最后猴子拿走255个,桃子总是是3121,请高人指点下。
还有楼主,你blog流量高我们都知道
41楼 dirdirdir3 4天前 12:10发表 [回复]
第三题,可以按字母的顺序搞个数组统计.
第四题,应该就是用hash表或者树
40楼 dirdirdir3 4天前 12:05发表 [回复]
第一题和第十二题不是非常相似,实际上就是n的m次方减(n-1)
n是分的堆数,m是分的次数.
39楼 chentaihan 4天前 10:04发表 [回复] [引用] [举报]
int rand10()
{
return rand7() * rand7() %11
}

你可能感兴趣的:(面试)