[编程题]拜访
现在有一个城市销售经理,需要从公司出发,去拜访市内的商家,已知他的位置以及商家的位置,但是由于城市道路交通的原因,他只能在左右中选择一个方向,在上下中选择一个方向,现在问他有多少种方案到达商家地址。
给定一个地图map及它的长宽n和m,其中1代表经理位置,2代表商家位置,-1代表不能经过的地区,0代表可以经过的地区,请返回方案数,保证一定存在合法路径。保证矩阵的长宽都小于等于10。
测试样例:
[[0,1,0],[2,0,0]],2,3
返回:2
class Visit { public: int countPath(vector<vector<int> > map, int n, int m) { // write code here int x1, y1, x2, y2; for(int i = 0; i < n; ++i) for(int j = 0; j < m; ++j) if(map[i][j] == 1){x1 = i; y1 = j;} else if(map[i][j] == 2){x2 = i; y2 = j;} int nx = std::abs(x1 - x2)+1; int ny = std::abs(y1 - y2)+1; vector<vector<int> > count(nx, vector<int>(ny, 0)); count[0][0] = 1; for(int i = 1; i < nx; ++i) if(map[x1+((x2>x1)?i:-i)][y1] != -1) count[i][0] = count[i-1][0]; for(int i = 1; i < ny; ++i) if(map[x1][y1+((y2>y1)?i:-i)] != -1) count[0][i] = count[0][i-1]; for(int i = 1; i < nx; ++i) for(int j = 1; j < ny; ++j) if(map[x1+((x2>x1)?i:-i)][y2+((y2>y1)?j:-j)] != -1) count[i][j] = count[i-1][j] + count[i][j-1]; return count[nx-1][ny-1]; } };
[编程题]旅途
原来是要到醋溜站台乘坐醋溜快车到醋溜港”,亮亮解出了地图隐藏的秘密,赶紧奔向醋溜站台,但到了之后,亮亮忧桑地发现,从醋溜站台到醋溜港沿途的每个车 站都有很多美女被他飒爽的英姿所吸引,只要经过车站就会被这些漂亮的女孩搭讪,但是现在亮亮一心想要寻找楚楚街而没空去搭理她们,所以亮亮希望在抵达醋溜 港的时候被搭讪的次数最少。问亮亮抵达醋溜港最少会被搭讪多少次?
输入描述:
第一行包含两个整数N(2<=N<=5000),M(1<=M<=50000)。N表示公有N个汽车站,M表示公有M条公路,起点为1,终点为N。 第二行包含N个整数(0<=K<=10000),第i个整数表示在第i站有K个美女想要搭讪亮亮。 接下来M行,每行包含两个整数P(1<=P<=N),Q(1<=Q<=N),代表P,Q两个站是有班车直达的。
输出描述:
一个整数,即亮亮抵达醋溜港最少需要被搭讪的次数。
输入例子:
5 5
0 1 1 3 6
1 2
1 4
2 3
3 5
4 5
输出例子:
8
#include<iostream> #include<vector> using namespace std; int Dijkstra(vector<vector<int>>& road, int N); int main() { int N, M; while (cin >> N >> M) { vector<int> station(N + 1); int Inf = 0x7fffffff; vector<vector<int>> road(N + 1, vector<int>(N + 1, Inf)); for (int i = 1; i <= N; i++) cin >> station[i]; for (int i = 0; i<M; i++) { int temp1, temp2; cin >> temp1 >> temp2; road[temp1][temp2] = station[temp2]; //1表示可以到达 road[temp2][temp1] = station[temp1]; road[temp1][temp1] = station[temp1]; road[temp2][temp2] = station[temp2]; } int res = Dijkstra(road, N); cout << res << endl; } } int Dijkstra(vector<vector<int>>& road, int N) { vector<bool> Mark(N + 1, true); int Inf = 0x7fffffff; vector<int> min(N + 1, Inf); int min_flag = Inf; int pos_flag; int start = 1; Mark[start] = false; //min[start] = road[start][start]; for (int i = 2; i <= N; i++) { if(road[start][i]!=Inf) //min[i] = min[start]+road[start][i]; min[i] =road[start][i]; if (min[i]<min_flag) { min_flag = min[i]; pos_flag = i; } } //以上初始化完成 int flag = 0; //while (flag != N - 1) while (Mark[N]) { min_flag = Inf; start = pos_flag; Mark[start] = false; for (int i = 2; i <= N; i++) { if (Mark[i] && road[start][i] != Inf) { if (min[start] + road[start][i]<min[i]) { min[i] = min[start] + road[start][i]; } } if (Mark[i] &&min[i]<min_flag) { min_flag = min[i]; pos_flag = i; } } flag++; } return min[N]+road[1][1]; }
以上使用邻接矩阵表示的,用邻接表表示更加的节省内存。
以下是邻接表的做法。
#include <iostream> #include <vector> #include <set> #include <string.h> #include <algorithm> #include <limits> using namespace std; int main(){ int N,M; while(cin>>N>>M){ vector<int> dp(N+1); for(int i=1; i<=N; i++) dp[i] = numeric_limits<int>::max(); vector<vector<int>> adj(N+1); set<int> visited; vector<int> w(N+1); for(int i=1; i<=N; i++) cin>>w[i]; dp[1] = w[1]; for(int i=1; i<=M; i++){ int p, q; cin>>p>>q; adj[p].push_back(q); adj[q].push_back(p); } // 初始化dp for(int i=0; i<adj[1].size(); i++){ dp[adj[1][i]] = dp[1] + w[adj[1][i]]; } while(visited.find(N) == visited.end()){ int u; // 找到下一个加入visited的点 int temp = numeric_limits<int>::max(); for(int j=1; j<=N; j++){ if(!visited.count(j) && dp[j] < temp){ temp = dp[j]; u = j; } } visited.insert(u); // relax for(int k=0; k<adj[u].size(); k++){ if(dp[u]+w[adj[u][k]] < dp[adj[u][k]]){ dp[adj[u][k]] = dp[u]+w[adj[u][k]]; } } } cout<<dp[N]<<endl; } return 0; }
字符编码
- 参与人数:280 时间限制:1秒 空间限制:32768K
- 算法知识视频讲解
题目描述
请设计一个算法,给一个字符串进行二进制编码,使得编码后字符串的长度最短。
输入描述:
每组数据一行,为待编码的字符串。保证字符串长度小于等于1000。
输出描述:
一行输出最短的编码后长度。
输入例子:
MT-TECH-TEAM
输出例子:
33
#include<iostream> #include<queue> #include<algorithm> #include<string.h> #define MAX 1000 using namespace std; int main() { char newString[MAX] = {0}; while(cin>>newString) { int i, j; int countNum = 0; //统计不同字符个数 int sum = 0; //记录编码后的长度 int first = 0, second = 0; //分别记录队列的最小两个值 int len = strlen(newString); priority_queue <int,vector<int>,greater<int> > huffmanQueue; //定义小值优先级高的队列 sort(&newString[0], &newString[len]); for(i = 0; i < len; ) { j = i; while((j < len)&&(newString[j] == newString[i])) { j++; } huffmanQueue.push(j - i); //将字符newString[i]的个数压入队列 i = j; countNum++; } for(i = 0; i < countNum - 1; i++) //霍夫曼编码步骤 { first = huffmanQueue.top(); huffmanQueue.pop(); second = huffmanQueue.top(); huffmanQueue.pop(); huffmanQueue.push(first + second); sum += first + second; } cout<<sum<<endl; }//while return 0; }
小米Git
- 参与人数:896 时间限制:1秒 空间限制:32768K
- 算法知识视频讲解
题目描述
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
class Solution { public: /** * 返回git树上两点的最近分割点 * * @param matrix 接邻矩阵,表示git树,matrix[i][j] == '1' 当且仅当git树中第i个和第j个节点有连接,节点0为git树的跟节点 * @param indexA 节点A的index * @param indexB 节点B的index * @return 整型 */ int getSplitNode(vector<string> matrix, int indexA, int indexB) { vector<bool> used(matrix.size(), false); vector<int> node_parent(matrix.size(),-1); queue<int> nums; nums.push(0); node_parent[0] = -1; used[0] = true; while (!nums.empty()) { int size = nums.size(); for (int i = 0; i < size; ++i) { int n = nums.front(); nums.pop(); for (int j = 0; j < matrix[n].size(); ++j) { if (matrix[n][j] == '1' && !used[j]) { node_parent[j] = n; used[j] = true; nums.push(j); } } } } vector<int> va; vector<int> vb; while (indexA != -1) { va.push_back(indexA); indexA = node_parent[indexA]; } while (indexB != -1) { vb.push_back(indexB); indexB = node_parent[indexB]; } reverse(va.begin(),va.end()); reverse(vb.begin(), vb.end()); int idx = 0; for (int i = 0; i < min(va.size(), vb.size()) ; ++i) { if(va[i] == vb[i]) idx = va[i]; else break; } return idx; } };