2015小米在线笔试题
2015-04-25 10:31
225 查看
1、问题:输入两个32位int型数,求其他们二进制位有多少不相同。
思路:对输入的两个数m,n进行异或操作结果为a,a的二进制中有多少位为1就是所求结果,
让a分别与32个只有一位为1其它是0的int数进行&操作若不为0就可以判断这位为1.
代码:
找到一种新方法:
2、问题:股市股票买卖,共有n天的股市价格情况,p[i]代表第i天的股市价格,你可以至多买卖两次股票(每次买股票时手中是没有股票的),问如何买卖收益才最大。
思路:m[i][j]代表从第i天到第j天股票价格的最低值,m[i][j]=min(m[i][j-1],p[j])
分两种情况:(1)买卖0次或1次,maxVal = p[i]-m[1][i-1];
(2)买卖两次v[i][j]代表分别在第i天和第j天卖出时收益最大值,则v[i][j] = p[i]-m[1][i-1]+p[j]-m[i+1][j-1],求v[i][j]中最大值。
代码:
3、问题:git是一种分布式代码管理工具,git通过树的形式记录文件的更改历史,比如:
base'<--base<--A<--A'
^
| --- B<--B'
小米工程师常常需要寻找两个分支最近的分割点,即base.假设git 树是多叉树,请实现一个算法,计算git树上任意两点的最近分割点。
(假设git树节点数为n,用邻接矩阵的形式表示git树:字符串数组matrix包含n个字符串,每个字符串由字符'0'或'1'组成,长度为n。matrix[i][j]=='1'当且仅当git树种第i个和第j个节点有连接。节点0为git树的根节点。)
输入例子:
输出例子:
int a = indexA, b = indexB;
while ( dep[a] > dep[b] ) {
a = fa[a];
}
while ( dep[a] < dep[b] ) {
b = fa[b];
}
while ( a != b ) {
a = fa[a];
b = fa[b];
}
以上方法仅是自己的思路,想来还有更好更快的方法希望可以看到。
思路:对输入的两个数m,n进行异或操作结果为a,a的二进制中有多少位为1就是所求结果,
让a分别与32个只有一位为1其它是0的int数进行&操作若不为0就可以判断这位为1.
代码:
#include <iostream> #include <algorithm> #include <cstring> using namespace std; int t[32] = {0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200, 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000, 0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000}; int main() { int m, n; int a; cin>>m>>n; a = m^n; //cout << a << endl; int oneNum = 0; for(int i=0;i<32;++i) { if((a&t[i])!=0) { oneNum++; } } cout << oneNum << endl; return 0; }
找到一种新方法:
#include <iostream> #include <algorithm> #include <cstring> using namespace std; int main() { int m, n; int a; cin>>m>>n; a = m^n; int oneNum = 0; while(a) { oneNum++; a = a&(a-1); } cout << oneNum << endl; return 0; }
2、问题:股市股票买卖,共有n天的股市价格情况,p[i]代表第i天的股市价格,你可以至多买卖两次股票(每次买股票时手中是没有股票的),问如何买卖收益才最大。
思路:m[i][j]代表从第i天到第j天股票价格的最低值,m[i][j]=min(m[i][j-1],p[j])
分两种情况:(1)买卖0次或1次,maxVal = p[i]-m[1][i-1];
(2)买卖两次v[i][j]代表分别在第i天和第j天卖出时收益最大值,则v[i][j] = p[i]-m[1][i-1]+p[j]-m[i+1][j-1],求v[i][j]中最大值。
代码:
#include <iostream> #include <algorithm> #include <cstring> using namespace std; const int NUM = 100; int m[NUM][NUM]; int p[NUM]; int v[NUM][NUM]; int main() { int n; while(cin>>n) { memset(m, 0 , sizeof(m)); memset(p, 0, sizeof(p)); memset(v, 0, sizeof(v)); for(int i=1;i<=n;++i) { cin>>p[i]; m[i][i] = p[i]; } for(int i=1; i<n; ++i) { for(int j=i+1; j<=n; ++j) { m[i][j] = min(m[i][j-1], p[j]); } } int maxVal = 0; for(int i=2; i<=n; ++i) { if(p[i]-m[1][i-1]>maxVal) { maxVal = p[i]-m[1][i-1]; } } for(int i=2; i<=n-2; ++i) { for(int j=i+2; j<=n; ++j) { if(p[i]-m[1][i-1]>0) { v[i][j] += p[i]-m[1][i-1]; } if(p[j]-m[i+1][j-1]) { v[i][j] += p[j]-m[i+1][j-1]; } if(v[i][j]>maxVal) { maxVal = v[i][j]; } } } cout << maxVal << endl; } return 0; }
3、问题:git是一种分布式代码管理工具,git通过树的形式记录文件的更改历史,比如:
base'<--base<--A<--A'
^
| --- B<--B'
小米工程师常常需要寻找两个分支最近的分割点,即base.假设git 树是多叉树,请实现一个算法,计算git树上任意两点的最近分割点。
(假设git树节点数为n,用邻接矩阵的形式表示git树:字符串数组matrix包含n个字符串,每个字符串由字符'0'或'1'组成,长度为n。matrix[i][j]=='1'当且仅当git树种第i个和第j个节点有连接。节点0为git树的根节点。)
输入例子:
[01011,10100,01000,10000,10000],1,2
输出例子:
1
思路:使用最短路径,存储下根节点到目标节点的路径,比较两条路径分离点。
int getSplitNode(vector<string> matrix, int indexA, int indexB) { bool flag[101]; int n = matrix.size(); int path[101][101]; int dist[101]; int prev[101]; stack<int> A, B; int NOPATH = 10000; for(int i=0; i<n; ++i) { for(int j=i; j<n; ++j) { if(matrix[i][j]=='0') { path[i][j] = NOPATH; path[j][i] = NOPATH; } else { path[i][j] = 1; path[j][i] = 1; } } } for(int i=1; i<n; ++i) { dist[i] = path[0][i]; flag[i] = false; if(dist[i]<NOPATH) { prev[i] = 0; } else { prev[i] = -1; } } prev[0] = -1; dist[0] = 0; flag[0] = true; for(int i=1; i<n; ++i) { int tmp = NOPATH; int u = 0; for(int j=1; j<n; ++j) if((!flag[j]) && dist[j]<tmp) { u = j; tmp = dist[j]; } flag[u] = 1; for(int j=1; j<n; ++j) if((!flag[j]) && path[u][j]<NOPATH) { int newdist = dist[u] + path[u][j]; if(newdist < dist[j]) { dist[j] = newdist; prev[j] = u; } } } while(indexA!=-1) { A.push(indexA); indexA = prev[indexA]; } while(indexB!=-1) { B.push(indexB); indexB = prev[indexB]; } int result = -1; while(!A.empty()&&!B.empty()) { int ta = A.top(); A.pop(); int tb = B.top(); B.pop(); if(ta==tb) { result = ta; } else { break; } } return result; }另一种方法:使用深度搜索记录下每个节点的父节点及深度然后如下搜索(dep为深度信息,fa为父节点)
int a = indexA, b = indexB;
while ( dep[a] > dep[b] ) {
a = fa[a];
}
while ( dep[a] < dep[b] ) {
b = fa[b];
}
while ( a != b ) {
a = fa[a];
b = fa[b];
}
以上方法仅是自己的思路,想来还有更好更快的方法希望可以看到。
相关文章推荐
- 京东2015在线笔试编程题--分苹果Java实现
- 2015小米实习生笔试题1 求两个数的不同位的个数
- 百度2015 在线笔试题(1)
- 2015阿里巴巴校招在线笔试题
- [笔试]小米2015笔试
- 阿里巴巴2015校园招聘前端在线笔试题
- 2015阿里巴巴前端实习生在线笔试题
- 百度2015 在线笔试题(1)
- 2015阿里巴巴前端实习生在线笔试题
- 京东2015在线笔试----编程题--分苹果
- 亚马逊2015校招在线笔试2
- 2015腾讯在线笔试的一道编程题
- 百度2015 在线笔试题(2)
- 2015 阿里巴巴 校招研发在线笔试题
- 滴滴出行2015在线笔试题目
- 京东2015在线笔试----编程题--分苹果
- 2015腾讯暑期实习招聘在线笔试(问答题)
- 百度2015 在线笔试题(2)
- 大众点评2015校招第一次在线笔试(Web前端工程师)
- 2015阿里巴巴前端实习生在线笔试考后总结