昨天参加今日头条和58转转的笔试,因为时间上有冲突,所以主要选择参加头条的笔试。

先说头条:

头条的题型:

一道改错题

三道编程题

一道设计题

感受:

做题目的的时候还是有点紧张的,因为突然遇到题目需要思考很长时间,而且不确定是否正确时,真的是着急。

做完头条笔试感觉真是好大差距,有大神三道编程全部AC,而我三道编程只能50%,0,0;

改错题一上来有点懵,半个多小时,最后还不知道改的对不对。

设计题基本是用一个套路来回答的,也不确定,但肯定不完善。

被虐的体无完肤。

下面主要记一下编程题:

第一题有思路,但是不知道哪里出的问题,最后只有50%通过。后来了解到,可能是输入输出使用cin/cout所致,在数据量比较大的时候使用scanf和printf效率会比较高。

但是第一题花费了过长的时间,大概接近50分钟。真的需要多写代码,熟练基本容器的使用。不然在写的时候,就会发现自己的代码上真的还是存在很大问题的。容器,迭代器。

第二题,因为只剩下十几分钟,刚开始题目都没有理解透。最后才读明白,可以用线段树。

第三题,直接没有时间去看。

下面贴一下大神的思路:

作者:Ck0123 链接:https://www.nowcoder.com/discuss/33986 来源:牛客网

(1)第一题:给一个二维平面,而且横纵坐标都不会重复(简化了排序),要求“不存在左上方还有点”的点集。因为数据量最大是50W,所以基本上用是O(nlogn)的方法解决。
首先按x坐标排个序(因为y不重复所以不用管),然后从后往前(此时保证当前点的x是比后面的x要小的),记录一个当前最大的Y,如果当前这个位置的y比Y还要大,那么明显这个位置的“左上方”不可能有点了。问题解决。
 
(2)第二题:一段长度是50W的数列,找一段区间,使得:这段区间里的最小值*这段区间值的总和 最大。换句话说就是:min*total是全部区间里最大的。
其实这样的题方法肯定有很多,但是突破口是一定的:从这个最小值入手。枚举这个最小值,然后问题就变成“怎么找这个数前面(和后面)第一个比它小的数的位置”,这个线段树可以解决。好像倍增也可以。当然还有别的方法只要是O(nlogn)肯定都是可以的。
 
 
(3)第三题:其实就是一个模拟不过是带优先队列的模拟,因为C++、Java都是自带优先队列的,所以问题不大。将程序员(因为哪个程序员做其实不重要)按目前手头上的idea实现结束时间加入一个优先队列(按结束时间来排序的),然后枚举当前的时间(从0到10000吧,假设),如果到了idea的“提出时间”,将它加入这个hr单独的优先队列里(idea要按照题目要求先排序),每个时间点都查询有没有空的程序员?有没有idea需要执行?按照这种思路大概就可以了。<!--说起来容易做起来难-->

总结:对于容器的使用要很重视,经常遇到同一类型需要用到pair容器的题目;

要提高编码的速度和质量,对于第一个题目,因为粗心可能浪费了有二十分钟调试。思路没有问题,都花在改代码上。。。

面对这样的编程笔试题目,一般,我觉得一道题目花费时间不应该超过25分钟。所以,当你在一道有思路的题目上花费超过半小时,那就说明你编码功底不够。

另外,面对题目吐过没有思路,说明对与常见算法与题目熟练度不够,需要多加练习。

实现代码,陆续补上!

1. 先上第一道改错题,感受一下:

改错如下:

  1. 作者:苏uu
  2. 链接:https://www.nowcoder.com/discuss/34136
  3. 来源:牛客网
  4.  
  5. dfsFind()函数
  6. 1. 没有处理node为空的边界条件;(我没考虑到)
  7. 2. 函数内的循环中node类型为Node*调用sons应为node->sons.size()和node->sons[i]; (考虑到了)
  8. 3. 函数递归调用是dep+1(考虑到了)
  9.  
  10. 修改如下:
  11. void dfsFind(Node* node, int dep, int counter[]) {
  12. if(node == nullptr) return;
  13. counter[dep]++;
  14. for(int i = 0; i < node->sons.size(); i++){
  15. dfsFind(node->sons[i], dep + 1, counter);
  16. }
  17. }
  18.  
  19. find函数中:
  20. 1. 树的深度最大为100000,则保存树各个深度的数组大小应为100001,且数组没有初始化,改为depCounter[100001] = {0}; (考虑到了)
  21. 2. 函数内用来记录最大节点的数目和的变量没有初始化,且记录最多节点所在的层数的变量明与maxDep同名,修改变量名为maxNodeLevel; (同名也考虑了,但是没有修改)
  22. 修改如下:
  23. int find(Node* root, int maxDep)
  24. {
  25. int depCounter[100001] = {0};
  26. dfsFind(root, 0, depCounter);
  27. int max = 0;
  28. int maxNodeLevel = 1;
  29. for(int i = 1; i < maxDep; i++) {
  30. if(depCounter[i] > max){
  31. max = depCounter[i];
  32. maxNodeLevel = i;
  33. }
  34. }
  35. return maxNodeLevel;
  36. }

2. 编程第一题:

 

我的实现代码(AC 50%)如下:

  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <math.h>
  5. #include <string>
  6.  
  7. using namespace std;
  8.  
  9. int find(vector<int> vec, int m){
  10. int res;
  11. for (int i = ; i < vec.size(); i++){
  12. if (m == vec[i]){
  13. return i;
  14. }
  15. }
  16. }
  17.  
  18. int main(){
  19. int N;
  20. cin >> N;
  21. int x, y;
  22. //vector<pair<int, int>> vec;
  23. vector<int> X;
  24. vector<int> Y;
  25.  
  26. for (int i = ; i < N; i++){
  27. cin >> x >> y;
  28. X.push_back(x);
  29. Y.push_back(y);
  30. }
  31. vector<int> X2(X);
  32. vector<int> Y2(Y);
  33. vector<int> res_x;
  34. vector<int> res_y;
  35.  
  36. sort(Y2.begin(), Y2.end());
  37. for (int j = ; j < Y.size(); j++){
  38. if (Y2[Y.size()-] == Y[j]){
  39. res_x.push_back(X[j]);
  40. res_y.push_back(Y[j]);
  41. break;
  42. }
  43. }
  44.  
  45. int temp = ;
  46. for (int i = Y2.size()-; i>=; i--){
  47. int res=find(Y, Y2[i]);
  48. if (X[res]>res_x[temp]){
  49. res_x.push_back(X[res]);
  50. res_y.push_back(Y[res]);
  51. temp++;
  52. }
  53. }
  54.  
  55. int len = res_x.size();
  56. //cout << len << endl;
  57. for (int i = ; i < len; i++){
  58. cout << res_x[i] << " " << res_y[i] << endl;
  59. }
  60.  
  61. system("pause");
  62. return ;
  63. }

思路好像正确,话说是因为cin/cout速度慢应该替换成scanf/printf.
等一个100%的代码;

我的改进版本:

  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<vector>
  4. #include<algorithm>
  5.  
  6. using namespace std;
  7.  
  8. bool cmp(const pair<int, int> p1, const pair<int, int> p2){
  9. return p1.second > p2.second;
  10. //这样是从大到小排序了;
  11. }
  12.  
  13. int main(){
  14.  
  15. int n;
  16. //cin >> n;
  17. scanf("%d", &n);
  18.  
  19. vector<pair<int, int>> vec;
  20. int x, y;
  21.  
  22. for (int i = ; i < n; i++){
  23. //cin >> x >> y;
  24. scanf("%d %d", &x, &y);
  25. vec.push_back(make_pair(x, y));
  26. }
  27.  
  28. sort(vec.begin(), vec.end(), cmp);
  29.  
  30. vector<pair<int, int>> res;
  31. res.push_back(make_pair(vec[].first, vec[].second));
  32.  
  33. //cout << res[0].first << " " << res[0].second << endl;
  34.  
  35. int temp = ;
  36. for (int i = ; i<n; i++){
  37. if (vec[i].first > res[temp].first){
  38. res.push_back(make_pair(vec[i].first, vec[i].second));
  39. temp++;
  40. }
  41. }
  42.  
  43. int len = res.size();
  44.  
  45. for (int i = ; i < len; i++){
  46. //cout << res[i].first << " " << res[i].second << endl;
  47. printf("%d %d\n", res[i].first, res[i].second);
  48. }
  49.  
  50. system("pause");
  51.  
  52. return ;
  53.  
  54. }

2. 编程第二题:

题目是求解区间最大值,第一个应该想到的高效方法就应该是线段树。

后来知道 这是个原题,POJ2796 使用单调栈,O(N)时间即能解决。

1)单调栈的思路:
Solution : 枚举+单调栈。看别人的解题报告学习了。单调栈这么厉害。对于这种题目,我们不能枚举区间(肯定超时),所以只能枚举最小值这个点,看看以这个点为最小值的区间向左和向右能伸展多远。这才是正确的思路。那么有了这个思路,如何实现呢。我们考虑单调栈!从第一个元素到最后一个元素一个一个入栈,我们发现,如果当前元素大于栈顶元素,那么这个元素是不能向前伸展的;同时如果当前元素小于栈顶元素,这个时候就要把栈中的元素一个一个弹出来,对于弹出来的元素,它扩展到当前元素就不能向后伸展下去了,因此对于弹出来的元素这个时候就可以计算左右端点形成区间与最小值的乘积了,维护一个最大值就好了,而对于当前元素的向前伸展端点就是新维护的栈顶元素的后一个元素了。这个题目有两个要注意的地方,第一,要手动在序列的最后加上一个-1。这样是为了能使得所有的元素都能入栈出栈。第二,对于序列中相等的元素,直接忽略就好了,其实这也是把相等的元素看成一个元素,最后计算的时候用的前缀和减前缀和,因此是可以计算到这些相等的元素的(并没有真正忽略!)。 

  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. const int MAXN=100000+5;
  5.  
  6. typedef long long LL;
  7.  
  8. int n;
  9. LL a[MAXN];
  10. LL stack[MAXN],top;
  11. LL left[MAXN],sum[MAXN];
  12.  
  13. int main()
  14. {
  15. //freopen("in","r",stdin);
  16. while(~scanf("%d",&n)){
  17. top=sum[0]=0;
  18. LL ans=-1,ansL=0,ansR=0;
  19. for(LL i=1;i<=n;i++)
  20. scanf("%lld",&a[i]),sum[i]=sum[i-1]+a[i];
  21. a[++n]=-1;
  22. for(LL i=1;i<=n;i++){
  23. if(!top||a[i]>a[stack[top-1]]){
  24. stack[top++]=i;
  25. left[i]=i;
  26. continue;
  27. }
  28.  
  29. if(a[i]==a[stack[top-1]])
  30. continue;
  31.  
  32. while(top>0&&a[i]<a[stack[top-1]]){
  33. top--;
  34. LL tmp=a[stack[top]]*(sum[i-1]-sum[left[stack[top]]-1]);
  35. if(tmp>ans)
  36. ans=tmp,ansL=left[stack[top]],ansR=i-1;
  37. }
  38. LL tmpL=stack[top];
  39. stack[top++]=i;
  40. left[i]=left[tmpL];
  41. }
  42. printf("%lld\n%lld %lld\n",ans,ansL,ansR);
  43. }
  44. return 0;
  45. }

 2)另一种,基于线段树的思路:

题解:思路来源于【http://acm.hdu.edu.cn/showproblem.php?pid=1506】这个题。

思想是:一a[i]为某个区间的最小值,初始区间为[i,i],左端向左延伸,右端向右延伸。最后维护最大值。

但是向前向后延伸的时候不能暴力,时间不允许,这里要用到DP的思想:

定义L[MAXN]=R[MAXN]=i;对于a[i]的L[i],刚开始的L[i]=i;如果a[i]>a[L[i]-1] -> L[i]=L[L[i]-1];2、R同理。

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include<cstdio>
  3. #include<stdio.h>
  4. #include<cstring>
  5. #include<iostream>
  6. #include<algorithm>
  7. using namespace std;
  8. typedef long long LL;
  9. const int MAXN = 100050;
  10. LL a[MAXN], sum[MAXN];
  11. LL L[MAXN], R[MAXN];
  12. int n;
  13. int main()
  14. {
  15. scanf("%d", &n);
  16. for (int i = 1; i <= n; i++)
  17. {
  18. scanf("%lld", &a[i]);
  19. sum[i] = sum[i - 1] + a[i];
  20. L[i] = R[i] = i;
  21. }
  22. a[0] = a[n + 1] = -1;//保证不会访问或者访问无效。
  23. for (int i = 1; i <= n; i++)
  24. {
  25. while (a[i] <= a[L[i] - 1])
  26. L[i] = L[L[i] - 1];
  27. }
  28. for (int i = n; i >= 1; i--)
  29. {
  30. while (a[i] <= a[R[i] + 1])
  31. R[i] = R[R[i] + 1];
  32. }
  33. LL ans = -1, l, r;
  34. for (int i = 1; i <= n; i++)
  35. {
  36. LL T = a[i] * (sum[R[i]] - sum[L[i] - 1]);
  37. if (ans < T)
  38. ans = T, l = L[i], r = R[i];
  39. }
  40. printf("%lld\n%lld %lld\n", ans, l, r);
  41. system("pause");
  42. return 0;
  43. }

下面再说58转转。

今日头条&58转转笔试的更多相关文章

  1. 剑指Offer——完美+今日头条笔试题+知识点总结

    剑指Offer--完美+今日头条笔试题+知识点总结 情景回顾 时间:2016.9.28 16:00-18:00 19:00-21:00 地点:山东省网络环境智能计算技术重点实验室 事件:完美世界笔试 ...

  2. 爬虫(猫眼电影+校花网+github+今日头条+拉钩)

    Requests+正则表达式爬取猫眼TOP100榜电影信息 MARK:将信息写入文件解决乱码方法,开启进程池秒爬. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...

  3. python-selenium登陆今日头条

    https://blog.csdn.net/a942242856/article/details/88379727 原文地址:http://www.bianbingdang.com/article_d ...

  4. DL4J之CNN对今日头条文本分类

    一.数据集介绍 数据来源:今日头条客户端 数据格式如下: 6551700932705387022_!_101_!_news_culture_!_京城最值得你来场文化之旅的博物馆_!_保利集团,马未都, ...

  5. 分析 ajax 请求并抓取 “今日头条的街拍图”

    今日头条抓取页面: 分析街拍页面的 ajax 请求: 通过在 XHR 中查看内容,获取 url 链接,params 参数信息,将两者进行拼接后取得完整 url 地址.data 中的 article_u ...

  6. 仿今日头条最强顶部导航指示器,支持6种模式-b

    项目中经常会用到类似今日头条中顶部的导航指示器,我也经常用一个类似的库PagerSlidingTabStrip,但是有时并不能小伙伴们的所有需求,所以我在这个类的基础上就所有能用到的情况做了一个简单的 ...

  7. 服务器端开发(Python/C++)-今日头条-拉勾网-最专业的互联网招聘平台

    服务器端开发(Python/C++)-今日头条-拉勾网-最专业的互联网招聘平台 服务器端开发(Python/C++)

  8. (android高仿系列)今日头条 --新闻阅读器 (三) 完结 、总结 篇

    从写第一篇今日头条高仿系列开始,到现在已经过去了1个多月了,其实大体都做好了,就是迟迟没有放出来,因为我觉得,做这个东西也是有个过程的,我想把这个模仿中一步一步学习的过程,按照自己的思路写下来,在根据 ...

  9. Android 高仿 频道管理----网易、今日头条、腾讯视频 (可以拖动的GridView)附源码DEMO

    距离上次发布(android高仿系列)今日头条 --新闻阅读器 (二) 相关的内容已经半个月了,最近利用空闲时间,把今日头条客户端完善了下.完善的功能一个一个全部实现后,就放整个源码.开发的进度就是按 ...

随机推荐

  1. Proxmox VE

    Proxmox虚拟化环境是基于QEMU/KVM和LXC的开源服务器虚拟化管理解决方案.我们可以使用集成的易于使用的WEB界面或通过CLI管理虚拟机,容器,高可用集群,存储和网络. Proxmox VE ...

  2. LoadRunner系列之---web_set_sockets_options,解决No buffer space available错误

    1. 如果在系统运行过程中出现"No buffer space available"或者出现大量连接出现wait的时候, 如何解决? 解决办法: 保证迭代结束后关闭所有的链接: 在 ...

  3. [UOJ206]Gap

    子任务$1$:直接找到最大值后从两边开始找,一步一步从左右到中间确定所有数,调用次数是$\left\lceil\dfrac n2\right\rceil$ 子任务$2$:先找到最大值$mx$和最小值$ ...

  4. Scala实战高手****第9课:Scala类和对象彻底实战和Spark源码鉴赏

    scala类和对象 RDD中创建_sc和deps相比java更加的简洁. 在Spark的例如SparkContext.sqlSpark等全局成员在完成实例化. 在唯一实例的时候一般不会去使用伴生对象a ...

  5. 最新Mac安装CocoaPods详细教程及各种坑解决办法

    网上有很多教程,但要么内容很老,要么不详细,要么各种坑的情况没写.最近买新电脑了,正好要走一遍这些流程,所以写下次教程. 一.安装RVM及更新Ruby 安装RVM的目的是为了更新Ruby,如果你的Ru ...

  6. Http报头Accept与Content-Type的区别(转)

    1.Accept属于请求头, Content-Type属于实体头. Http报头分为通用报头,请求报头,响应报头和实体报头. 请求方的http报头结构:通用报头|请求报头|实体报头 响应方的http报 ...

  7. React Conf 2017 干货总结 1: React + ES next = ♥

    React Conf 2017在加利福尼亚州的圣克拉拉万豪酒店圆满落幕,这已经是Facebook举办的第三届React官方大会了.虽然不能参会,但是作为前端开发者,我们当然不能错过这个绝佳的学习契机. ...

  8. Chrome DevTools 代码覆盖率功能详解

    共 1812 字,读完需 3 分钟.工欲善其事必先利其器,前端周刊本周起每周会加餐 1 篇工具技巧,里面辅以动图,让大家看完就能学会,并上手使用.本文会介绍 Chrome Canary 新增的代码覆盖 ...

  9. 数组中的push()和pop()方法

    push()方法可以接受任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度. pop()方法是从数组末尾移除最后一项,减小数组的length值,然后返回移除的项. var arr = [ ...

  10. spring+mybatis项目启动报错Initializing Spring root WebApplicationContext

    这个问题很怪异,各种各样的情况都会导致这个问题的出现,主要是由于sping加载读取配置文件的时候出了问题.我在处理mybatis的时候出现了这个问题,后来排查发现,在mybatis的配置文件中如果有大 ...