欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

2022字节跳动研发笔试题题解(C++)

时间:2023-04-29

第一题:
用STL的string的 find 和 erase:

首先,通过find找到需要删除的字符/字符串的位置:

string str;
string target;
int pos = str.find(target);

然后通过erase进行删除:

n = target.size();
str = str.erase(pos,n);
第二题:
https://www.nowcoder.com/questionTerminal/c0803540c94848baac03096745b55b9b?toCommentId=3154435

#includeusing namespace std; int main(){ long long N,D; while(cin>>N>>D){ long long res=0; long long *a=new long long[N]; for(long long i=0,j=0;i>a[i]; while (i >= 2 && (a[i] - a[j]) > D) { j++; } res +=(i - j-1) * (i - j) / 2; } cout<

我当时做的时候纠结的就是如何才能做到不重不漏啊(梦回高中了属于是),我的算法本来想用双循环找一串符合条件的数来Cn3的,感觉重合了,一时间想不出怎么搞就跳了,这里的话相当于锁定了一个最大数,然后让其他数来进行组合,这样的话就可以实现

这里好像是有坑的,int 还会超限。。long都不行,必须得long long。。
第三题:
雀魂启动!
我写这题的时候一直在想如何判断胡,感觉好难顶,常用函数调用还不是太熟练,而且用的是dfs,不禁令人感叹。

核心代码:

bool isHu(vector nums) {//其实是一个dfs的过程 if (nums.empty()) return true;//递归出口 int cnt = count(nums.begin(), nums.begin() + 4, nums[0]);//记录与首元素相同的数字的个数 if (nums.size() % 3 != 0 && cnt >= 2) {//取雀头(只会取一次) if (isHu(vector(nums.begin() + 2, nums.end()))) return true; } if (cnt >= 3) {//取刻子(三个相同的数字) if (isHu(vector(nums.begin() + 3, nums.end()))) return true; } if (count(nums.begin(), nums.end(), nums[0] + 1) > 0 && count(nums.begin(), nums.end(), nums[0] + 2) > 0) {//取顺子 int val = nums[0]; nums.erase(nums.begin());//去掉一个首元素(顺子的第一个) nums.erase(find(nums.begin(), nums.end(), val + 1));//去掉一个首元素+1(顺子的第二个) nums.erase(find(nums.begin(), nums.end(), val + 2));//去掉一个首元素+2(顺子的第三个) if (isHu(nums)) return true; } return false;}

for (int i = 1; i <= 9; ++i) {//遍历下一张可能的牌 if (count(nums.begin(), nums.end(), i) == 4) continue;//最多就4张,真的不能再多了 nums.insert(lower_bound(nums.begin(), nums.end(), i), i);//插入i,函数lower_bound()在first和last中的前闭后开区间,进行二分查找。返回从first开始的第一个大于或等于val的元素的地址。如果所有元素都小于val,则返回last的地址。注意:数组必须是排好序的数组。 if (isHu(nums)) res.push_back(i); //判断是否ok nums.erase(lower_bound(nums.begin(), nums.end(), i));//恢复原始nums数组 }

第四题:
特征提取
https://www.nowcoder.com/questionTerminal/5afcf93c419a4aa793e9b325d01957e2?answerType=1&f=discussion

核心知识:map,pair
用双字典轮滚解决
用一个老字典和一个新字典,最后的时候把老的换成新的,新的变空等待输入,这种方法适用于过去数据要传递到未来的情况。(连续问题)

#includeusing namespace std;int main(){ int N,m; cin>>N; while(N--){ cin>>m; int f,x,y; map,int> pre;//历史帧数 map,int> now;//现在帧数 int max_ = 0; for(int i =0; i< m;i++){ cin>>f; for(int j =0; j< f;j++){ cin>>x>>y; if(pre.count({x,y})){ now[{x,y}] = pre[{x,y}] + 1;//又出现了一次,就是老的加1 }else{ now[{x,y}] = 1;//从来没有出现过 } if(now[{x,y}]>max_){//时时更新任何一个连续帧 max_ = now[{x,y}]; } } //如果这帧为0,那么就不会保留任何历史信息了,因为now在这轮没有任何内容。 pre.clear();//清空历史,把now变为历史 pre.swap(now);//now 置空,同时,now变成上一个,这样的话连续问题就可以解决 } cout<

// 查询关键字为key的元素的个数,在map里结果非0即1
size_t count( const Key& key ) const; //

第五题:
https://www.nowcoder.com/questionTerminal/3d1adf0f16474c90b27a9954b71d125d?answerType=1&f=discussion
第一篇题解,很详细。
他的代码没有注释,所以写一下基于注释的代码

// 代码#includeusing namespace std;int main() { int n; cin >> n; vector > cost(n,vector(n));//初始化 for(int i=0;i> cost[i][j];//输入 int all = 1<<(n-1);//位运算,取2个n-1次方 vector > dp(n,vector(all));//初始化 for(int i=0;i(i-1))&1)==0){ for(int k=1;k>(k-1))&1)==1){ dp[i][j] = min(dp[i][j],cost[i][k]+dp[k][j^(1<<(k-1))]); }//带着循环看。就是取这几个的最小值。 } } } } cout << dp[0][all-1] << endl;}

第六题:
略。
第七题:
机器人跳跃问题
数学归纳法了属于是

方法一:
归纳:

#include#include #include using namespace std; int main(){ int N; int ans = 0; cin >> N; vectorD(N,0); for(int i = 0;i>D[i]; for(auto i in D){ ans+=D[i]/pow(2,i); } cout<

方法二,逆着解。

#include#include #include using namespace std; int main(){ int N; int ans = 0; cin >> N; vectorD(N,0); for(int i = 0;i>D[i]; for(int j=N-1;j>=0;j--){ ans = ceil((D[j]+ans)/2.0);//注意c++中除法整数/整数为0,ceil向上取整要整数/float类型 } cout<

差不多就这样吧,焯!

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。