目录
2017年4月26日 阿里巴巴笔试编程题 股票
题目:
题目所给的代码:
#include <iostream>
#include <vector>
#include <cstdio>
#include <algorithm>
using namespace std;
/*请完成下面这个函数,实现题目要求的功能*/
/*当然,你也可以不按照下面这个模板来作答,完全按照自己的想法来 ^-^ */
/******************************开始写代码******************************/
double StockGod(int n, int m, double p, const vector<vector<double>>& prices)
{
}
/******************************结束写代码******************************/
int main()
{
int n = 0;
int m = 0;
double p = 0;
cin >> n >> m >> p;
vector<vector<double>> prices;
for(int i = 0; i < m; ++i) {
prices.push_back(vector<double>());
for(int j = 0; j < n; ++j) {
double x = 0;
cin >> x;
prices.back().push_back(x);
}
}
double final = StockGod(n, m, p, prices);
printf("%.1f\n", final);
return 0;
}
题目的意思是有n个股票,有m个交易期可以交易,问1元最多可以变成多少元
我刚开始的思路是,只选择1个股票,在每个交易期选择买入或者卖出,最后看最大收获是多少
代码:
double StockGod(int n, int m, double p, const vector<vector<double>>& prices)
{
double ans = 1, a = 1, b = 1;
for (int j = 0; j < n; j++)
{
a = 1, b = 1;
for (int i = 1; i < m; i++)
{
if (prices[i][j] >= prices[i - 1][j])b *= prices[i][j] /prices[i - 1][j];
else
{
if (b*(1 - p)>1)a *= b*(1 - p);
b = 1;
}
}
if (b*(1 - p)>1)a =a* b*(1 - p);
if (ans < a)ans = a;
}
return ans;
}
通过率是60%
仔细一想,这个思路是不行的,比如下面的输入示例
2 3 0.1
1 2 1 3 2 3
所以我新的思路是,手中的股票不一定一直是同一个股票,可以换,但是要保证手中永远只有一种股票(或者只有现金)
代码:
double StockGod(int n, int m, double p, const vector<vector<double>>& prices)
{
int k = -1;
double ans = 1-p, a = 1;
for (int j = 0; j < n; j++)if (a < prices[1][j] / prices[0][j])
{
a = prices[1][j] / prices[0][j];
k = j;
}
ans *= a;
for (int i = 2; i < m; i++)
{
a = 1;
if (a < prices[i][k] / prices[i-1][k])a = prices[i][k] / prices[i-1][k];
for (int j = 0; j < n; j++)if (a < prices[i][j] / prices[i-1][j]*(1-p))
{
a = prices[i][j] / prices[i-1][j] * (1 - p);
k = j;
}
ans *= a;
}
return ans>1?ans:1;
}
通过率还是60%
我感觉正确的解答应该是动态规划,但是没想出来怎么实现。
2017年4月26日 阿里巴巴笔试编程题 调度算法
题目:
暂无截图
题目说什么真没看懂,只知道要实现一个调度算法
题目给的代码:
#include <map>
#include <vector>
#include <queue>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
/*
a
/ \
b c
/ \ / \
d e f g
\ / \
h j i
\
k
\
l
a:托马斯(Thomas)
b:艾德华(Edward)
c:亨利(Henry)
d:高登(Gordon)
e:詹姆士(James)
f:培西(Percy)
g:托比(Toby)
h:达克(Duke)
j:唐纳德&道格拉斯(Donald&Douglas)
j:奥利佛(Oliver)
k:亚瑟(Arthur)
l:艾蜜莉(Emily)
*/
struct BT
{
int key;
BT *l, *r;
};
BT* create_n(int key)
{
}
bool train_schedule(BT* rt, int index)
{
if (!rt)
return false;
map<int, string> m_train;
m_train[0] = "Thomas";
m_train[1] = "Edward";
m_train[2] = "Henry";
m_train[3] = "Gordon";
m_train[4] = "James";
m_train[5] = "Percy";
m_train[6] = "Toby";
m_train[7] = "Duke";
m_train[8] = "Donald&Douglas";
m_train[9] = "Oliver";
m_train[10] = "Arthur";
m_train[11] = "Emily";
}
int main()
{
int i = 0;
BT *rt = create_n('a');
rt->l = create_n('b');
rt->r = create_n('c');
rt->l->l = create_n('d');
rt->l->r = create_n('e');
rt->r->l = create_n('f');
rt->r->r = create_n('g');
rt->r->l->r = create_n('h');
rt->r->r->r = create_n('i');
rt->r->r->l = create_n('j');
rt->r->r->l->r = create_n('k');
rt->r->r->l->r->r = create_n('l');
std::cin >> i;
train_schedule(rt, i);
return 0;
}
我的代码:
#include<string.h>
BT* create_n(int key)
{
BT *p = new BT();
p->key = key - int('a');
p->l = p->r = NULL;
return p;
}
bool train_schedule(BT* rt, int index)
{
if (!rt)
return false;
map<int, string> m_train;
m_train[0] = "Thomas";
m_train[1] = "Edward";
m_train[2] = "Henry";
m_train[3] = "Gordon";
m_train[4] = "James";
m_train[5] = "Percy";
m_train[6] = "Toby";
m_train[7] = "Duke";
m_train[8] = "Donald&Douglas";
m_train[9] = "Oliver";
m_train[10] = "Arthur";
m_train[11] = "Emily";
if (rt->key == index)
{
train_schedule(rt->l, rt->l->key);
train_schedule(rt->r, rt->r->key);
printf("%s\n", m_train);
return true;
}
if (train_schedule(rt->l, index))return true;
return train_schedule(rt->r, index);
}
通过0%
2017阿里巴巴笔试
1,有4副相同的牌,每副牌有4张不同的牌.先从这16张牌中,随机选4张出来.然后,在这4张牌中随机选择一张牌,然后把抽出的一张放回3张中,再随机选择一张牌.与上次选出的牌一样的概率是()
A、1/4 B、1/3 C、2/5 D、1/2 E、2/3 F、3/4
正确答案:C
题目中说的相同的牌、牌一样指的都是牌的内容一样,我们考虑2次取出的是不是同一张牌。
是同一张,p1=1/4
不是同一张,p2=3/4*p3
p3是在除了第一次取出的那张牌之外的15张牌中任取一张牌,得到相同的牌的概率
p3=3/15
所以,答案是p1+p2=2/5
2,某体校选择校服,每套校服都包括短袖运动衫,长袖运动衫,厚外套,运动长裤和运动短裤组成.每种运动服有个备选方案.
老师请了部分学生来挑选自己喜欢的校服.结果发现任意3个学生都至少在一种运动服上选择互不相同,那么老师最多邀请了()名学生参加挑选.
A、7 B、8 C、9 D、10 E、11 F、12
正确答案:B
3,给定的一个长度为N的字符串str,查找长度为P(P<N)的字符串在str中的出现次数.下面的说法正确的是()
A、不存在比最坏时间复杂度O(NP)好的算法
B、不存在比最坏时间复杂度O(N^2)好的算法
C、不存在比最坏时间复杂度O(P^2)好的算法
D、存在最坏时间复杂度为O(N+P)的算法
E、存在最坏时间复杂度为O(log(N+P))的算法
F、以上都不对
正确答案:D
因为有KMP的存在,所以ABC是错的,D是对的。
至于E,无论如何str至少要扫描一遍,不可能少于N
4,下面关于一个类的静态成员描述中,不正确的是()
A、静态成员变量可被该类的所有方法访问
B、该类的静态方法只能访问该类的静态成员函数
C、该类的静态数据成员变量的值不可修改
D、子类可以访问父类的静态成员
E、静态成员无多态特性
正确答案:C
5,下面这个代码输出的是()
#include <iostream>
#include <vector>
usingnamespacestd;
int main(void)
{
vector<int> array;
array.push_back(100);
array.push_back(300);
array.push_back(300);
array.push_back(300);
array.push_back(300);
array.push_back(500);
vector<int>::iterator itor;
for (itor = array.begin(); itor != array.end(); itor++)
{
if (*itor == 300)
{
itor = array.erase(itor);
}
}
for (itor = array.begin(); itor != array.end(); itor++)
{
cout << *itor << "";
}
return 0;
}
A、100 300 300 300 300 500
B、100 3OO 300 300 500
C、100 300 300 500
D、100 300 500
E、100 500
F、程序错误
正确答案:C
每次运行erase,itor会指向被删除元素的下一个元素。
所以,第1个300和第3个300会被删掉,另外2个300会留下。
6,struct st { int *p; int i; char a; }; int sz=sizeof(struct st);
如下C程序,在64位处理器上运行后sz的值是什么?
A、24 B、20 C、16 D、14 E、13 F、12
正确答案:C
可以参考这个文章:点击打开链接
偏移量是变量的大小的整数倍,是为了寻址的效率。
在64位机器中指针、long、unsigned long都是8字节,其他不变。
所以这里,指针p的偏移量为0,大小为8
然后整数i的偏移量为8,大小为4
然后字符a的偏移量为12,大小为1,加起来是13。
将13补足为8、4、1的倍数就是16
7,在自由交换的情况下,只考虑偏好,小张用自己的小刀换了小王的橡皮.关于这个交换以下说法错误的是:
A、小张觉得橡皮比小刀更好
B、小王觉得小刀比橡皮更好
C、小张和小王总的财富里没有发生变化
D、小张和小王的效用值增加了
E、如果把小王换成小吴,那么这个交换可能就不会发生
F、小刀和橡皮等值
正确答案:F
8,有100个金币,分给10个人.第一个金币等概率地分给10个人之一.之后的每一个金币分配给第K个人的概率正比于这个人已经持有的金币数+1.在这样的分配机制下,关于每个人最终的金币个数的分布的说法错误的是()
A、每个人得到的金币的个数的期望是相等的
B、每个人的金币个数接近均匀分布
C、第一个金币给哪个人,哪个人的最终金币个数的期望就会更大
D、在中间的某个阶段金币个数越多的人,未来获得金币的可能性越大
E、以上说法都是正确的
F、以上说法都是不正确的
正确答案:B
这个答案就比较诡异了。
讲道理,B肯定是错的,ACD肯定是对的,但是这样的话,EF也是错的咯。
9,某创业团队的一个很大的办公室(障碍和遮挡可以忽略)里有一个WIFI源,有1个工位由于距离WIFI源太远而接收不到信号.为了提高该工位的联网质量,准备在工位和WIFI信号源之间安装一个无线AP(相当于中继的,可以中转该工位上的计算机和WIFI之间的信号).只考虑从WIFI发出的信号,如果AP离WIFI源太近,就起不到中继的作用,如果AP离工位太远则可能连不上WIFI.因此AP有一个最佳的安装位置,那么关于AP最佳安装位置的说法正确的是()
A、如果WIFI源功率越大,那么AP最佳安装位置越靠近WIFI源
B、如果WiFi源功率越大,那么AP最佳的安装位置越靠近工位
C、WIFI源功率和AP最佳安装位置无关
D、AP最佳安装位置在工位和WIFI信号源连线之外
E、AP最佳安装位置在工位和WIFI信号源连线中点
F、以上说法都不对
正确答案:B
10,下面的哪种排序算法在算复杂度平均不是O(nlogn)的?
A、快速排序 B、桶排序 C、合并排序 D、二叉树排序树排序 E、堆排序
正确答案:B
基于比较的排序,最好的也就是平均O(n log n)了
桶排序是基于计算的排序,介于n和n log n之间,如果桶特别多的话,效率接近n
11,下面哪个不是线性表?
A、循环链表 B、队列 C、栈 D、关联数组 E、空字符串数组 F、双向链表
正确答案:D
12,在100-999这900个自然数中,若将组成这个数的三个数字认为是三条线段的长度,那么是三条线段组成一个等腰三角形(包括等边)的共有()个.
A 45 B 91 C 121 D 142 E 156 F 165
正确答案:F
先考虑aab这种形式的数。
a和b都是从1到9,具体说来:
a=1,b=1
a=2,b=1 to 3
a=3,b=1 to 5
a=4,b=1 to 7
a=5 to 9,b=1to 9
所以有1+3+5+7+5*9=61种
加上aba和baa的形式,61*3=183
其中111 to 999这9个数有重复计算,最后的结果是183-9*2=16
13,7的2014次方这个整数的十位数字数是()
A 0 B 1 C 3 D 4 E 5 F 7
正确答案:D
只需要最基本的同余即可。
7^4=2401≡1(mod 100)
2014%4=2
所以7^2014≡7^2=49(mod 100)
所以十位是4
14,有无限的水源,一个5L无刻度桶和一个7L无刻度桶,则只利用这两个无刻度桶,将不能获得()L水
A 2 B 3 C 6 D 8 E 11 F 以上均能获得
正确答案:F
2L和3L都是非常容易获取的。
只要能获得2L和3L,那么除了1之外的任何正整数,都是可以获取的了。
例如6=2+2+2,8=2+2+2+2,11=3+2+2+2+2
初一看,好像就是10进制。
但是在十进制下成立不代表在15-19进制成立。
比如15*15=225,这个式子只在10进制下成立。
240*12=2880表示成方程是:(2*n*n+4*n)*(n+2)=2*n*n*n+8*n*n+8*n
这是个恒等式。
也就是说,只要是n>8,240*12=2880在n进制里面都成立。
为什么会有这种现象呢?
其实很简单,因为在计算240*12得到2880的时候,并没有进位。
例如,11*12=132这个式子在n(n>3)进制里面都是成立的。
左子树-右子树-根
假设开始有a个红球,b个黑球,都取出了c个
那么p=a/(a+b),q=(a-c)/(a-c+b-c)
q<q化简即是b<a
char *a是指针数组,里面存放的是3个指针,每个指针都指向一个字符串。
初始pa指向第一个指针,pa++之后pa指向第二个指针,所以最后的*pa就是第二个指针。
这个指针指向字符串“at”
我觉得这个题目里面的状态一词完全应该改成体积。
这样,只有A是对的。
这里面只有插入排序在最优条件下可以达到θ(n)的时间复杂度
2017阿里巴巴实习生笔试题
n个元素扫描一遍。
前面m个元素构建1个最小堆,后面n-m个元素,每个元素都加入到堆中,然后删掉堆中的最小元素,然后调整为新的堆。
带权路径长度为:(12+13+8)*2+(1+4)*3=81
题目貌似没有说清楚,像1111或者1222这样的数是不算的。
如果重复的数字是1,那么1的位置有3种情况,另外2个数字有9*8=72种情况,所以是3*72=216种情况
如果重复的数字不是1,那么重复的数字有9种情况,另外一个数字有8种情况,它的位置有3种情况,所以也是216种
加起来是432
改选之前,获胜的概率是1/3,改选之后,获胜的概率是2/3
首先,先序的第一个是A,所以根是A
然后,根据中序序列可知,A的左子树的中序是CB,右子树的中序是EFDIHJG
再根据先序序列,左子树的先序是BC,右子树的先序是DEFGHIJ
这样,问题就化简成了2个较小的子问题了,最后可以得到完整的二叉树
把出栈的序列划分为若干个段,每个段里面的元素都是递减的。取出每个段的段首
ABCD:A+B+C+D,段首ABCD
DCBA:DCBA,段首D
ACBD:A+CB+D,段首ACD
BCDA:B+C+DA,段首BCD
ACDB:A+C+DB,段首ACD
DCAB:DCA+B,段首DB
如果段首是递增的,那么就是正确的出栈顺序,否则就是错误的出栈顺序。
A车平均10分钟一辆,B车平均14分钟一辆。
所以,平均每70分钟就有12辆车
即,每35/6分钟就有1辆
所以平均等待时间为35/12分钟
不放回地取三次和直接一次取三个是一样的
p=5*5*5/C,其中C=15*14*13/6
A对应的开发,既然是乙的好友那么就不是乙,既然是最年轻的,那么就不是丙,所以是甲。
C对应的开发,既然比丙年轻,那么就不是丙,那么就只能是乙了。
因为周六和周日连续的2天都是说真话,所以应该是一样的回答。
但是前6天没有连续2天是一样的回答,说明第七天要么是周六,要么是周日。
如此即可验证。