2014年阿里校招笔试题目

题目

一、单选题

1.假设把整数关键码K散列到N个槽列表,以下哪些散列函数是好的散列函数
A: h(K)=K/N;
B: h(K)=1;
C: h(K)=K mod N;
D: h(K)=(K+rand(N)) mod N, rand(N)返回0到N-1的整数
选择C,解释:由于hash的特性在于常数的时间执行插入、删除和查找操作,用D作为hash函数无法满足该条件。
2.下面排序算法中,初始数据集的排列顺序对算法的性能无影响的是:

A: 堆排序 B:插入排序

C: 冒泡排序 D:快速排序

选择A
3. 下面说法错误的是:
A: CISC计算机比RISC计算机指令多
B: 在指令格式中,采用扩展操作码设计方案的目的是为了保持指令字长不变而增加寻址空间
C:增加流水线段数理论上可以提高CPU频率
D:冯诺依曼体系结构的主要特征是存储程序的工作方式
选择B,保持指令字长度不变而增加指令操作的数量;
      D解析
  冯诺依曼体系结构的主要特点:存储程序控制(要求计算机完成的功能,必须事先编制好相应的程序,并输入到存储器中,计算机的工作过程是运行程序的过程);程序由指令构成,指令和数据都用二进制表示;指令由操作码和地址码构成;机器以cpu为中心
4. 不属于冯诺依曼体系结构必要组成部分是:
A:CPU B: Cache C:RAM D:ROM
B,解释:冯诺依曼体系结构必要组成部分:运算器、控制器、存储器、输入设备、输出设备,Cache属于缓存
5. 一个栈的入栈序列式ABCDE则不可能的出栈序列是:
A:DECBA B:DCEBA C:ECDBA D:ABCDE
C
6.你认为可以完成编写一个C语言编译器的语言是:
A:汇编 B:C语言 C:VB D:以上全可以
D
7. 关于C++/JAVA类中的static成员和对象成员的说法正确的是:
A:static成员变量在对象构造时候生成
B: static成员函数在对象成员函数中无法调用
C: 虚成员函数不可能是static成员函数
D: static成员函数不能访问static成员变量
C,解析:static没有this指针
9:某进程在运行过程中需要等待从磁盘上读入数据,此时进程的状态将:
A: 从就绪变为运行 B:从运行变为就绪
C: 从运行变为阻塞 D:从阻塞变为就绪
C,解释:I/O事件让进程从running->waitting。
10:下面算法的时间复杂度为:
Int f(unsigned int n)
{
If(n==0||n==1)
Return 1;
Else
Return n*f(n-1);
}
A: O(1) B:O(n) C:O(N*N) D:O(n!)
B,解释:此题虽然简单,但容易错选!!!
11: n从1开始,每个操作可以选择对n加1或者对n加倍。若想获得整数2013,最少需要多少个操作。
A:18 B:24 C:21 D;不可能
A,
解释:

直接进行计算,奇数减1除2,偶数直接除以2,2013>1006>503>251>125>62>31>15>7>3>1

再反过来计算从1到2013的次数,为18次

数学方法->从 2013 倒推, 奇数 减一,偶数 除2, 编程实现->是一个明显的bfs题目,编程实现为18,bfs代码:此实现转载自: http://blog.csdn.net/wzy_1988/article/details/11790511
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. #define FINAL 2013  
  5.   
  6. #define MAX 25  
  7.   
  8. typedef struct num {  
  9.     int d, time;  
  10. } num;  
  11.   
  12.   
  13. typedef struct queue {  
  14.     int front, rear, count;  
  15.     num data[10000000];  
  16. } queue;  
  17.   
  18.   
  19. void enQueue(queue *q, num d)  
  20. {  
  21.     q->data[q->rear ++] = d;  
  22.     q->count ++;  
  23. }  
  24.   
  25. num deQueue(queue *q)  
  26. {  
  27.     num res;  
  28.     res = q->data[q->front ++];  
  29.     q->count --;  
  30.   
  31.     return res;  
  32. }  
  33.   
  34.   
  35. int main(void)  
  36. {  
  37.     int flag = 0;  
  38.   
  39.     num bt, one, two, s;  
  40.   
  41.     bt.d = 2;  
  42.     bt.time = 1;  
  43.   
  44.     queue *q = (queue *)malloc(sizeof(queue));  
  45.     q->front = q->rear = q->count = 0;  
  46.   
  47.     enQueue(q, bt);  
  48.   
  49.     while (q->count > 0) {  
  50.         s = deQueue(q);  
  51.   
  52.         if (s.d == FINAL) {  
  53.             flag = 1;  
  54.             printf("%d\n", s.time);  
  55.             break;  
  56.         }  
  57.   
  58.         one.d = s.d + 1;  
  59.         one.time = s.time + 1;  
  60.         if (one.d <= FINAL && one.time <= MAX) {  
  61.             enQueue(q, one);  
  62.         }  
  63.   
  64.         two.d = s.d * 2;  
  65.         two.time = s.time + 1;  
  66.         if (two.d <= FINAL && two.time <= MAX) {  
  67.             enQueue(q, two);  
  68.         }  
  69.   
  70.         printf("%d\n", q->count);  
  71.     }  
  72.   
  73.     if (flag == 0)  
  74.         printf("不可能!\n");  
  75.   
  76.     return 0;  
  77. }  
改编后的递归非递归实现如下:
 /************************************************************************
*   程序功能:n从1开始,每个操作可以选择对n加1或者对n加倍。若想获得整数2013,最少需要多少个操作。
*   输入:整数n,
    输出:按上述操作获得n需要的操作个数
*   思路:从输入的整数n开始,若n为奇数,则减1,操作次数加1;否则n减半,操作次数加1.
*   测试例子:op(2013)
*   测试输出:18
*   创    建:2014/3/30
************************************************************************/
#include<cassert> 
int op(int n)
{
assert( n>0 );
int time = 0;
    if(1 == n)
time = 0;
else 
{    
if( n & 0x1 == 1)//n是奇数
{
n = n-1;
   time += 1;//操作次数+1
}
time += op( n >> 1 ) ;//加上除2后的操作次数
time += 1 ;           //除2,操作次数+1
}
return time;
}
/************************************************************************
*   程序功能:n从1开始,每个操作可以选择对n加1或者对n加倍。若想获得整数2013,最少需要多少个操作。
*   输入:整数FINAL,
    输出:按上述操作获得n需要的操作个数
*   思路:1、一个新数据结构num,num.d表示当前到达的数,num.time表示到达数的操作次数;辅助结构:队列
              2、声明两个变量num one,two,初始数均为2,对应的操作次数为1;
      3、one.d加1,one.time加1,当one.d<=FINAL时one进栈,否则输出;
     two.d*2,two.time加1,当two.d<=FINAL时two进栈,否则输出;
             4、当队列非空时出队列,转入3。
*   测试例子:op(2013)
*   测试输出:18
*   创    建:2014/3/30
************************************************************************/
/******************模拟栈******************/  
typedef struct num {  
    int d;
int time;  
} num;   
typedef struct queue {  
    int front, rear, count;  
    num data[10000000];  
} queue;   
void enQueue(queue *q, num d)  
{  
    q->data[q->rear ++] = d;  
    q->count ++;  
}   
num deQueue(queue *q)  
{  
    num res;  
    res = q->data[q->front ++];  
    q->count --;   
    return res;  
}   
/*************************************/
void op2 (int FINAL)
{
   assert(FINAL>1);
    int flag = 0;  //结束标志,flag=1,表示增长到输入数FINAL 
    num bt, one, two, s;  
  
    bt.d = 2;//起点从数2开始  
    bt.time = 1; //2变成1仅需要操作一次 
  
    queue *q = (queue *)malloc(sizeof(queue));  
    q->front = q->rear = q->count = 0;  
  
    enQueue(q, bt);  
  
    while (q->count > 0) 
{  
        s = deQueue(q);  
  
        if (s.d == FINAL) 
{  //到达输入的整数FINAL
            flag = 1;  
            printf("%d\n", s.time);  
            break;  
        }  
  
        one.d = s.d + 1;  
        one.time = s.time + 1;  
        if (one.d <= FINAL )  
            enQueue(q, one);  
        two.d = s.d * 2;  
        two.time = s.time + 1;  
        if (two.d <= FINAL )  
            enQueue(q, two);    
       // printf("%d\n", q->count);  
    }  
  
    if (flag == 0) 
{
        printf("不可能!\n");
   
}
}  
12:对于一个具有n个顶点的无向图,若采用邻接表数据结构表示,则存放表头节点的数组大小为:

A: n B: n+1 C: n-1 D:n+边数

A,解析:无向图有n个顶点,e条边,则邻接表有n个头结点和2e个表结点;
               边稀疏(e << n(n-1)/2)时,使用邻接表表示图比邻接矩阵节省空间  
13.考虑一个特殊的hash函数h,能将任一字符串hash成一个整数k,其概率p(k) = 2^(-k),k = 1,2,3,4,....对于一个未知大小的字符串集合S中的每一个元素取hash值所组成的集合为h(S).若h(s)中最大元素max h(s) =10,那么s的大小期望是
A:1024 B:512 C:5 D:10
此题没有叙述清楚。
14.如下函数,在32bit系统foo(2^31-3)的值是:
Int foo(int x)
{

Return x&-x;

}

A: 0 B: 1 C:2 D:4

C,解析:必须注意^是异或,不是指数

15.对于顺序存储的线性数组,访问节点和增加节点删除节点的时间复杂度为:

A: O(n),O(n) B:O(n),O(1) C:O(1),O(n) D:O(n),O(n)

C
16:在32为系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是:
Struct A
{
int a;
short b;
int c;
char d;
};

Struct B
{
int a;
short b;
char c;
int d;
};

A: 16,16 B:13,12 C:16,12 D:11,16

C,解析:注意字节对齐。
17.袋中有红球,黄球,白球各一个,每次任意取一个放回,如此连续3次,则下列事件中概率是8/9的是:
A: 颜色全相同 B:颜色全不相同C:颜色不完全相同 D:颜色无红色

C,解释:(1)颜色全相同:C(1,3) / 27 =  1 / 9(2)颜色全不相同:3 * 2 * 1 / 27 = 2 / 9 (4)颜色无红色: 2 * 2 * 2 / 27 = 8 / 27 (3)颜色不完全相同 = 1 - P(颜色完全相同) = 1 - 1 / 9 = 8 / 9
18.一个洗牌程序的功能是将n张牌的顺序打乱,以下关于洗牌程序的功能定义说法最恰当的是:

A: 每张牌出现在n个位置上的概率相等

B: 每张牌出现在n个位置上的概率独立

C: 任何连续位置上的两张牌的内容独立

D: n张牌的任何两个不同排列出现的概率相等

D
解析:貌似AD都对,其实不然,《算法导论》习题5.3-4表明,A的条件较弱,其结果不是均匀随机排列;
          D可以产生均匀随机排列,每个排列出现的概率是1/n!.
以下是模拟洗牌的两种实现:
/************************************************************************
*   程序功能:n个数存入数组,模拟洗牌
*   输入:整数数组arr[],数组大小N
    输出:一次洗牌操作
*   创    建:2014/3/30
*   说    明:此实现依据《STL源码剖析》random_shuffle的实现
*   思    路:每次迭代中arr[i]与arr[0]~arr[i]的一个随机数交换
*   测    试:int a[]={1,2,3,4,5,6,7};
       int N=sizeof(a)/sizeof(a[0]);
            shuffleArray_STL(a,N);        
************************************************************************/    
#include<time.h>
void shuffleArray_STL(int arr[],int N)//《STL源码剖析》random_shuffle的C++实现  
{  
    int i, loc, tmp;  
    time_t t;  
  
    srand((unsigned int)time(&t));  
      
    // 洗牌算法  
    for (i = 1; i < N; i ++) {  
        loc = rand() % (i + 1); //或者加上 if( loc != i ) 
        tmp = arr[loc];  
        arr[loc] = arr[i];  
        arr[i] = tmp;  
    }  
  
    for (i = 0; i < N; i ++)  
        printf("%d ", arr[i]);  
    printf("\n");  
}
/************************************************************************
*   程序功能:n个数存入数组,模拟洗牌
*   输入:整数数组arr[],数组大小N
    输出:一次洗牌操作
*   创    建:2014/3/30
*   说    明:此实现依据《算法导论》5.3节的均匀随机排列,每个排列出现的概率1/n!
*   思    路:每次迭代中arr[i]与arr[i]~arr[N-1]的一个随机数交换,这样第i次迭代后,arr[i]保持不变
               int a[]={1,2,3,4,5,6,7};
          int N=sizeof(a)/sizeof(a[0]);        
          shuffleArray_introductionOfAlgorithms(a,N);
************************************************************************/  
int rand_ab(int a,int b)//均匀随机生成[a,b]内的一个数
{
   time_t t;  
    srand((unsigned int)time(&t));
return ( a + rand() % ( b-a+1 ) );
}
void shuffleArray_introductionOfAlgorithms(int arr[],int N)
{  
    int i, loc, tmp;  
    time_t t;  
  
    srand((unsigned int)time(&t));  
      
    // 洗牌算法  
    for (i = 0; i < N; i ++) {  
        loc = rand_ab(i,N-1); //arr[i]<---->arr[i]~arr[N-1],第i次迭代后,arr[i]保持不变
        tmp = arr[loc];  
        arr[loc] = arr[i];  
        arr[i] = tmp;  
    }     
    for (i = 0; i < N; i ++)  
        printf("%d ", arr[i]);  
    printf("\n");  
}  
19.用两种颜色去染排成一个圈的6个棋子,如果通过旋转得到则只算一种,一共有多少种染色:
A: 10 B:11 C:14: D:15

答案共14种

分析:题目意思是说旋转后相同的颜色排布算一种。相当于棋子没有区别,只有位置的相对关系。

设两种颜色为黑白

全黑1种+全白1种=2

1黑5白(1种)+1白5黑(1种)=2种

2黑4白(2个黑的可以紧挨着,2个黑的中间隔1个棋子,两个黑的中间隔2个棋子)共3种

4黑2白同2黑4白对称:3种

3黑3白:3个黑的连在一起(1种),3个黑的任意两个之间不相邻(1种),3个黑的有两个挨着,另外一个与这两个棋子都不相邻(2种)

共4种

特别是另外一个与这两个棋子都不相邻的情况,有两种,刚开始以为是对称的算一种了,而实际上是两种,因为这种通过旋转是转不到一样的。

所以总共有2+2+3+3+4=14种

20.递归式的先序遍历一个n节点,深度为d的二叉树,则需要栈空间的大小为:
A: O(n) B:O(d) C:O(logn) D:(nlogn)
B

二、多选题

21.两个线程运行在双核机器上,每个线程主线程如下,线程1:x=1;r1=y;线程2:y=1;r2=x;

X和y是全局变量,初始为0。以下哪一个是r1和r2的可能值:

A: r1=1,r2=1

B: r1=1,r2=0

C:r1=0,r2=0

D:r1=0,r2=1

ABD,解析:注意r1和r2不可能同时为0,当一个有赋值时,必然完成了对另一个x或y的赋值
22.关于Linux系统的负载,以下表述正确的是:

A: 通过就绪和运行的进程数来反映

B: 通过TOP命令查看

C: 通过uptime查看

D: Load:2.5,1.3,1.1表示系统的负载压力在逐渐变小

BC

23.关于排序算法的以下说法,错误的是:

A: 快速排序的平均时间复杂度O(nlogn),最坏O(N^2)

B:堆排序平均时间复杂度O(nlogn),最坏O(nlogn)

C:冒泡排序平均时间复杂度O(n^2),最坏O(n^2)

D:归并排序的平均时间复杂度O(nlogn),最坏O(n^2)

D,解释:归并排序最坏的时间复杂度也是O(nlogn)

24.假设函数rand_k会随机返回一个【1,k】之间的随机数(k>=2),并且每个证书出现的概率相等。目前有rand_7,通过调用rand_7()和四则运算符,并适当增加逻辑判断和循环控制逻辑,下列函数可以实现的有:

A:rand_3 B:rand_21 C:rand_23 D:rand_49

ABCD

填空和问答

25.某二叉树的前序遍历-+a*b-cd/ef,后续遍历abcd-*+ef/-,问其中序遍历序列为
注:此类型题一般中序遍历序列必须已知,否则无法求解,不知道此题是不是出错了???
26.某缓存系统采用LRU,缓存容量为4,并且初始为空,那么在顺序访问以下数据项的时候:1,5,1,3,5,2,4,1,2

出现缓存直接命中的次数为:(),最后缓存即将淘汰的是()

3,5,
解析:考察《操作系统》基础知识
27.两个较长的单链表a和b,为了找出节点node满足node in a并且node in b。请设计空间使用尽量小的算法
求两个链表的公共节点题。
思路:由于只要求空间尽量小,所以可以两个链表排序后,再查找,空间O(1),
28.存储数据量超出单节点数据管理能力的时候,可以采用的办法有数据库sharding的解决方案,也就是按照一定的规律把数据分散存储在多个数据管理节点N中(节点编号为0,1,2,,,,N-1)。假设存储的数据时a 请完成为数据a计算存储节点的程序

hash(key) = key % N

29.宿舍内5个同学一起玩对战游戏,每场比赛有一些人作为红方,一些人作为蓝方,请问至少需要多少场比赛,才能使得任意两个人之间有一场红方对蓝方和蓝方对红方的比赛

分析:一次划分中,某方可以有1人,另一方有4人或某方有2人,另一人有3人。

要使任意两个人之间有一场红方对蓝方和蓝方对红方的比赛,假设5个同学为A,B,C,D,E,相当有有向图的5个节点,任意两个节点间有两个方向的边连接。

即总的节点关系有(5个节点中选取两个节点)A(5,2)=5*4=20个关系。

而一次比赛(一次划分)能够生成的关系(一方两人一方三人的划分)c(2,1)*c(3,1)=2*3=6或者(一方四人一方一人的划分)c(4,1)*(c(1,1)=4*1=4,

所以一场比赛(一次划分)最多生成的关系次数为6

所以需要20/6=3.33..即至少需要4场比赛

扩展:此题亦可求至多需要多少场比赛,才能使得任意两个人之间有一场红方对蓝方和蓝方对红方的比赛?

需要20/4=5

对问题的补充:

其他题目:

写一个程序, 要求功能:求出用1,2,5这三个数不同个数组合的和为100的组合个数。

如:100个1是一个组合,5个1加19个5是一个组合。。。。 请用C++语言写。

方法一三个for循环

方法二:转载自:http://blog.csdn.net/yuucyf/article/details/6679149

由题知:假设X为1的个数,Y为2的个数,Z为5的个数,那么满足X+2*Y+5*Z = 100

所以X+5*Z = 100 - 2*Y,很明显X+5*Z是一个偶数,并且Z是<=20的,那么对Z做循环

Z=0, X=100,98,...,0

Z=1,X=95,93,...,1

Z=2,X=90,88,...0

.

.

.

Z=19,X=5,3,1

Z=20,X=0

所以结果只要求出100以内的偶数,95以内的奇数...最后是5以内的奇数再加一次就行了

对于一个奇数N求0到N之间的奇数个数为N/2+1,同样的偶数个数为N/2+1

代码如下:

  1. int Sum_Combination1(int nSum)  
  2. {  
  3.     int nCnt = 0;  
  4.     for (int i32I = 0; i32I <= nSum; i32I += 5)  
  5.     {  
  6.         nCnt += (i32I + 2)/2;  
  7.     }  
  8.   
  9.     return nCnt;  
  10. }  

将二叉树的两个孩子换位置,即左变右,右变左。不能用递规

解决方案:

1)根结点入队列

2)取队首元素并出列,并将该元素左右儿子进行交换

3)如果队列不为空则跳到步骤2

复制代码
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
using namespace std;


struct tree{
    tree *right;
    tree *left;    
}*list;
void solve(tree *list){
    queue <tree*> Q;
    Q.push(list);
    while(!Q.empty()){
        tree *tmp = Q.front();
        Q.pop();
        swap(tmp->right, tmp->left);
        if(tmp->right != NULL)
            Q.push(tmp->right);
        if(tmp->left != NULL)
            Q.push(tmp->left);
    }
}

38头牛中选出3头跑得最快的,使用一个每次只能供6头比赛的场地,要求用最快的方法

解决方案:

38只取6只一组,6*6,取前3名,得3*6+2=20,用了6次

20只取5只一组,取前3名,得到3*4=12,用了4次

12只分两组取前3名,得3*2=6,用了2次

最后再加1次

累计13次

O(logn)Fibonacci数列

解决方案:

(转) 

下面介绍一种时间复杂度是O(logn)的方法。在介绍这种方法之前,先介绍一个数学公式:

{f(n), f(n-1), f(n-1), f(n-2)} ={1, 1, 1,0}n-1

(注:{f(n+1), f(n), f(n), f(n-1)}表示一个矩阵。在矩阵中第一行第一列是f(n+1),第一行第二列是f(n),第二行第一列是f(n),第二行第二列是f(n-1)。)即:

[ f(n), f(n-1)                      

  f(n-1), f(n-2)]            = 

有了这个公式,要求得f(n),我们只需要求得矩阵{1, 1, 1,0}的n-1次方,因为矩阵{1, 1, 1,0}的n-1次方的结果的第一行第一列就是f(n)。这个数学公式用数学归纳法不难证明。感兴趣的朋友不妨自己证明一下。

现在的问题转换为求矩阵{1, 1, 1, 0}的乘方。如果简单第从0开始循环,n次方将需要n次运算,并不比前面的方法要快。但我们可以考虑乘方的如下性质:

/  an/2*an/2                      n为偶数时
an=
        \  a(n-1)/2*a(n-1)/2            n为奇数时

要求得n次方,我们先求得n/2次方,再把n/2的结果平方一下。如果把求n次方的问题看成一个大问题,把求n/2看成一个较小的问题。这种把大问题分解成一个或多个小问题的思路我们称之为分治法。这样求n次方就只需要logn次运算了。

实现这种方式时,首先需要定义一个2×2的矩阵,并且定义好矩阵的乘法以及乘方运算。当这些运算定义好了之后,剩下的事情就变得非常简单。完整的实现代码如下所示。

    /************************************************************************
*   程序功能:O(logn)求Fibonacci数列
*   思    路:下面介绍一种时间复杂度是O(logn)的方法。在介绍这种方法之前,先介绍一个数学公式:


{f(n), f(n-1), f(n-1), f(n-2)} ={1, 1, 1,0}n-1


(注:{f(n+1), f(n), f(n), f(n-1)}表示一个矩阵。在矩阵中第一行第一列是f(n+1),第一行第二列是f(n),第二行第一列是f(n),第二行第二列是f(n-1)。)


有了这个公式,要求得f(n),我们只需要求得矩阵{1, 1, 1,0}的n-1次方,因为矩阵{1, 1, 1,0}的n-1次方的结果的第一行第一列就是f(n)。
这个数学公式用数学归纳法不难证明。感兴趣的朋友不妨自己证明一下。


现在的问题转换为求矩阵{1, 1, 1, 0}的乘方。如果简单第从0开始循环,n次方将需要n次运算,并不比前面的方法要快。但我们可以考虑乘方的如下性质:


/  an/2*an/2                      n为偶数时
an=
        \  a(n-1)/2*a(n-1)/2            n为奇数时


要求得n次方,我们先求得n/2次方,再把n/2的结果平方一下。如果把求n次方的问题看成一个大问题,
把求n/2看成一个较小的问题。这种把大问题分解成一个或多个小问题的思路我们称之为分治法。这样求n次方就只需要logn次运算了。
*    输   入:待求的第n个斐波那契数
*    输   出:第第n个斐波那契数
*    说   明:第n个数:  1 2 3 4 5 6 7 8 ...
              斐波那契: 1 2 3 5 8 13 
*    调   用:cout<<matrixpower(6).m_00<<endl;             
************************************************************************/

struct matrix2by2{
    matrix2by2(
        long  m00 = 0,
        long  m01 = 0,
        long  m10 = 0,
        long  m11 = 0
        )
        :m_00(m00), m_01(m01), m_10(m10), m_11(m11){}


    long  m_00;
    long  m_01;
    long  m_10;
    long  m_11;
};
matrix2by2 matrixmultiply(const matrix2by2 &a, const matrix2by2 &b){
    return matrix2by2(
        a.m_00 * b.m_00 + a.m_01 * b.m_10,
        a.m_00 * b.m_01 + a.m_01 * b.m_11,
        a.m_10 * b.m_00 + a.m_11 * b.m_10,
        a.m_10 * b.m_01 + a.m_11 * b.m_11
        );
}
matrix2by2 matrixpower(int n){
    matrix2by2 matrix;
    if(n == 1)
        matrix = matrix2by2(1, 1, 1, 0);
    else if(n % 2 == 0){
        matrix = matrixpower(n/2);
        matrix = matrixmultiply(matrix, matrix);
    }
    else if(n % 2 == 1){
        matrix = matrixpower((n-1)/2);
        matrix = matrixmultiply(matrix, matrix);
        matrix = matrixmultiply(matrix, matrix2by2(1, 1, 1, 0));
    }
    return matrix;
}
//更简明的实现
// *  调   用:cout<<power(6).a[0][0]<<endl;  
struct matrix                  //定义2*2的矩阵 
{
    int a[2][2];
    matrix(int aa,int b,int c,int d)
{
a[0][0] = aa;
   a[0][1] = b;
   a[1][0] = c;
   a[1][1] = d;
}
matrix(){};


};

matrix mul(matrix& x,matrix& y)  // 矩阵乘法 x = x*y
{

return matrix(x.a[0][0]*y.a[0][0] + x.a[0][1]*y.a[1][0],
  x.a[0][0]*y.a[0][1] + x.a[0][1]*y.a[1][1],
   x.a[1][0]*y.a[0][0] + x.a[1][1]*y.a[1][0],
x.a[1][0]*y.a[0][1] + x.a[1][1]*y.a[1][1] );
}


matrix power(int n){
    matrix mat;
    if(n == 1)
        mat = matrix(1, 1, 1, 0);
    else if(n % 2 == 0){
        mat = power(n/2);
        mat = mul(mat, mat);
    }
    else if(n % 2 == 1){
        mat = power((n-1)/2);
        mat = mul(mat, mat);
        mat = mul(mat, matrix(1, 1, 1, 0));
    }
    return mat;
}
//非递归实现
// *  调   用:cout<<power2(6).a[0][0]<<endl; 
matrix power2(int n)
{
//非递归代码:
 if(n == 1)
        return matrix(1, 1, 1, 0);
matrix result ;
matrix base (1,1,1,0);
bool flag=false;
if(n&1)  flag=true; 
n = n >> 1;
result = base;
while(n)
{
base = mul(base, base);
if( (n&1) && (n != 1) )
{
   base = mul(result, base);

}
n = n >> 1;
}
if(true == flag)
    result = mul(result, base);
else
    result = base;
return result;


}


To speed up data access , we build cache system. In one system , The L1 cache access time is 5 ns , the L2 cache access time is 50 ns and the memory access time is 400 ns. The L1 cache miss rate is 50% , the L2 cache miss rate is 10%. The average data access time of this system is:(5 Points)

自己的答案:

 average data access time=P1*5+(1-P1)*[P2*(5+50)+(1-P2)*(5+50+400)]

其中,P1=50%,P2=(1-10%)

定义一个二进制数字串的“长度”为从最右侧开始算起连续1的个数(说明,如果最右侧为0,则长度为0,如果最右侧为1,则开始数连续的1的个数作为长度)。例如length(100011)=2,length(100000)=0,请分析一个随机的N位字串的“长度”的期望值是多少

注意这个长度是从最右侧算起的,比如length(111011)=2,即使,字符串左边出现更长的长度

解答:

长度: 0    1       2     3   4 ... n-1          n

概率   P0  P1     P2  .....        P(n-1)     Pn

求P0,只需要从右到左的第1个位置为0即可,即P0=2^(n-1)/2^n

求P1,只需要从右到左的第1个位置为1,第2个位置为0即可,即P1=2^(n-2)/2^n

同理可求其他的概率

 期望值E=0*P0+1*P1+2*P2+...n*Pn

以下题目转载自:http://blog.csdn.net/zhanglei0107/article/details/11856777

某公司的销售专家需要拜访商家,假设本市总共有M家商家,某公司派了N位销售专家来拜访本市的商家。假设专家之间互不通信,每位专家随机选择K个商家。如果有多位专家拜访了一个商家,我们称之为拜访碰撞。问发生拜访碰撞的概率是多少?


          

特别情况:当K=1时

  

有3种规格的糖果,分别为每包6颗,每包9颗,每包140颗,如果需要8颗的话,就要对糖果进行拆包。当所需的糖果数字N>=某个数量时

,糖果便不需要进行拆包,问N的值为多少

分析6=3*2,9=3*3,6和9均为3的倍数,而任意因子个2和3的组合可以组成2,3,4,5,6,7..(即>=2的任意整数),所以

6和9的组合可以表示>=6的3的倍数。而140%3=2(取模运算).。所以140+6=146可以用6,9,140的组合表示。

即可以表示>=146(即140+3*n,n>=2)对3求模余2的所有的数,所有数对3求模要么余0(已经可以表示3的倍数),要么余1,要么余2(余2的>=146的数已经可以表示)

要对3求模余1可以使140翻倍至280。280对3求模便余1,说明140的2倍已经可以表示对3求模余1的数。那么280+3*n的组合(3n>=6)便可以表示

(即>=286的数),这样所有的数已经可以表示。是不是答案就是286呢,答曰不是的。

因为285可以被3整除,284对3求模余2且>146,所有284便是答案

此题的解法用了取模的思想。所有的整数数对某个数k取模要么为0,1,2,3,...k-1。只要能覆盖着k种情况,便可以表示所有的整数


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

多则惑少则明

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值