Shopee 春招笔试分享
首先吐槽一下,急急忙忙花了30分钟做完选择题之后才发现选择题占分 60,后面三个编程题才占 40 ...
第一题 比较版本号
给两个版本号 a 和 b ,用逗号和一个空格分隔开,判断大小。假设两个版本的版本段是一致的.
- a<b 输出 -1
- a=b 输出 0
- a>b 输出 1
样例输入
1.10.2, 1.2.10
样例输出
1
思路
- split(str): 将两个版本号 string 分割,得到两个 vector
- trim(str): 对于 vector
里的每个元素, 去掉前面多余的 0, 例如 {10,0001,11},做 trim 后得到 {10,1,11} - compare_str(a, b):从头到尾对两个 vector 做比较
trim 操作我不知道是不是必须的,我这里一次性考虑了。
代码
100% 测试样例
#include<iostream> #include<string> #include<vector> using namespace std; void trim_str(string& a){ int i=0; while(i<a.size() && (a[i]=='0'||a[i]==' ')) i+=1; a = a.substr(i); } int compare_str(string a, string b){ trim_str(a); trim_str(b); if (a.size() > b.size()) return 1; // a>b; else if (a.size() < b.size()) return -1; // a<b; else{ if (a<b) return -1; else if (a==b) return 0; else return 1; } } vector<string> split(string a, char seg){ vector<string> result; string tmp_str = ""; for(auto c: a){ if( c==seg ){ result.push_back(tmp_str); tmp_str = ""; }else{ tmp_str.push_back(c); } } result.push_back(tmp_str); return result; } int main(){ string v1; string v2; while(cin >> v1 >> v2){ v1 = v1.substr(0, v1.size()-1); vector<string> v1_segs = split(v1, '.'); vector<string> v2_segs = split(v2, '.'); int cmp = 0; for(int i=0; i<v1_segs.size(); i++){ cmp = compare_str(v1_segs[i], v2_segs[i]); if (cmp!=0) break; } cout << cmp << endl; } }
第二题 数组去重
输入一个有序 int 数组,去重规则:数字 x 的出现次数不超过 x,问去重后数组的最大长度
样例输入
1 1 1 2 2 2 3 3 3
样例输出
6
思路
这道题我觉得主要是怎么方便的把一行输入读进来,其他的逻辑非常简单。
代码
100% 测试样例
#include<iostream> #include<vector> #include<string> using namespace std; int main(){ int a; vector<int> input; while(cin>>a){ char ch = getchar(); input.push_back(a); if (ch == '\n'){ // 开始处理 input 数组 int curr_num=-1; int curr_rest=-1; int l=0; for(auto c: input){ if(curr_num != c){ curr_num = c; curr_rest= c-1; l ++; }else{ if (curr_rest>0){ curr_rest --; l++; } } } cout << l << endl; // input 数组处理结束,重新开始。 input.clear(); } } }
第三题 有多少条路
经典动态规划题,给定 m 和 n 表示矩阵的长宽,小明从左上角走到右下角一共有多少条路,只等向右走或者向下走。注意数字溢出问题。 m n 的值都不超过 50.
样例输入
3 2
样例输出
3
思路
数据一定会溢出 int 的,第一考虑的是用动态规划的状态转移矩阵用 unsigned long,但是这样会爆内存。所以用了两个 unsigned 矩阵,一个矩阵用来存 sum/UINT_MAX, 另一个用来存 sum%UINT_MAX。
代码
100% 测试用例
#include <iostream> #include <vector> #include <climits> #define MAX_N 51 using namespace std; void init(vector<vector<unsigned>>& matrix1, vector<vector<unsigned>>& matrix2){ for(int i=0;i<MAX_N;i++){ unsigned z1 = 0; unsigned z2 = 1; vector<unsigned> line1(MAX_N, z1); vector<unsigned> line2(MAX_N, z2); matrix1.push_back(line1); matrix2.push_back(line2); } for(int i=1; i<MAX_N;i++){ for(int j=1;j<=MAX_N;j++){ unsigned long sum1 = (unsigned long)matrix1[i-1][j]+(unsigned long)matrix1[i][j-1]; unsigned long sum2 = (unsigned long)matrix2[i-1][j]+(unsigned long)matrix2[i][j-1]; unsigned long sum = sum1 * UINT_MAX + sum2; matrix1[i][j] = (unsigned)(sum/UINT_MAX); matrix2[i][j] = (unsigned)(sum%UINT_MAX); } } } int main(){ int m, n; vector<vector<unsigned>> matrix1; vector<vector<unsigned>> matrix2; init(matrix1, matrix2); while (cin>>m>>n) { cout << (unsigned long)((unsigned long)matrix1[m-1][n-1]*UINT_MAX + (unsigned long)matrix2[m-1][n-1])<< endl; } }#Shopee##笔试题目##笔经#