一、 算法&程序设计
1、打魔兽DOTA,选英雄,M个英雄围成一圈供玩家选择,天灾军团和近卫军团交替,一边选一个,直至选完(为保证两边人数相等,M是偶数)。为了增加趣味性,制定选英雄规则如下:
按照顺时针方向,两队一边选一个(选英雄不区分阵营),选中的英雄会消失,不参与下一轮选择。强制规定每次选择英雄,都只能选择与最后被选走英雄顺时针相隔两个人的英雄。
你是一个具有高尚情操的玩家,于是让对方团队先选择,而你自己最后选择。同时,你又是一位很强势的玩家,你可以指定对方第一位选手选择哪个英雄。请你设计一个程序,求出如何指定对方第一位选手的选择,可以让你自己最终能够选择到“牛头人酋长”,程序语言不限。
答:DOTA为10个玩家。
#define “牛头人酋长” object
#define “第一位选手的选择 first
1)假设M>=28,则first位于object的逆时针方向,距离为26。
2)假设M<10, 不可能
3)10<28 (偶数),用以下方式计算
node * createLinkedList(int m) //建立一个长度为n的循环列表,给各节点赋值(1~m), 返回表头
{
node *p=new node(1);
node *q=p;
for(int i=1;i
{
p->next=new node(i+1);
p=p->next;
}
p->next=q;
return q;
}
struct node
{
int num;
node * next;
}
int find(int m) //则first位于object的逆时针方向,距离为out
{
if(m>=28) return 26;
else if(m<10) return -1;
else
{
node * p=createLinkedList(m);
for(int i=1;i<10;i++)
{
p->next=p->next->next; //删除p的next
p=p->next->next; //移动p两个位置
}
int out=p->num-2;
if(out<0) out=out+n;
return out;
}
}
2、设计一个函数实现获得原始字符串的子串的功能,从某个偏移位置开始,获取长度为n的子串,希望函数能够比较健壮。
bool getStr(const char* scr,const char* ob,const int begin,const int n) //begin从0开始记
{
if(strlen(scr)
if(strlen(ob)!=n) return false;
char *p=scr;
for(int i=0;i
strncpy(ob,p,n);
return true;
}
use case:
char *scr="fjkajfdkl;jfalajfj";
int n=10;
char *ob=new char(n+1);
ob[n]='/0';
getStr(scr,ob,3,n);
....
delete ob;
ob=0;
3、有一个单向链表,如何检测该链表中存在环(若链表中下一个元素指向该元素或前面的元素则判断为存在环)?给出该算法时间复杂度和空间复杂度的说明。(可以写伪码)
答:从表头开始,定义两个指针p1,p2。p1一次走一步,p2一次走两步,这称之为一次执行;若某次执行之后两个指针指向同一个元素(p1==p2)则说明存在环(最多执行length次,length为链表长度),若p2指向NULL,那么是没环的。
时间复杂度:O(n)=n
空间复杂度:O(n)=2
二、系统设计题
1、 设计一个多线程安全的内存池类pool,提供如下两个功能:
a) void *pool::malloc(unsigned size) 分配size大小的内存
b) void pool::free(void *p) 释放p指向的内存
要求给出思路、主要数据结构和算法,关键部分可用C/C++或伪代码辅助描述,并可结合图示。
2、 工程中的许多问题可抽象成矩阵相乘的模型,请设计实现方案,输入两个矩阵A、B,输出A*B。