网易2019校招笔试,今日头条2019校招笔试(前两道),搜狐2019校招笔试三道题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011268787/article/details/81591883

网易2019校招笔试题

1. 丰收

题目:

就是堆了几堆的南瓜,然后给出几个数字作为序号,猜是第几堆里面的南瓜

思路:

思路不难,就是进行累加,然后找出数字在第几个堆里。让人不爽的是时间复杂度败给了调用函数的,就是这个lower_bound(first *itor,last *itor,const int T)函数,它指向在[first,last]标记的有序序列中可以插入value,而不会破坏容器顺序的第一个位置,而这个位置标记了一个不小于value 的值

代码:

#include <bits/stdc++.h>

using namespace std;

int sum[100005];

int main() {
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        int a;
        scanf("%d", &a);
        sum[i] = sum[i - 1] + a;
    }
    int q;
    scanf("%d", &q);
    while (q--) {
        int d;
        scanf("%d", &d);
        int pos = lower_bound(sum, sum + n + 1, d) - sum;
        printf("%d\n", pos);
    }
    return 0;
}

2. 瞌睡

题目:

就是一个傻逼小孩上课打瞌睡,然后还想让同桌叫醒他,让他再学那么几分钟,让我们求这个傻逼小孩上课收益最大(能听到课内容最多)

思路:

思路不难,就是滑动窗口的动态规划,这个听了好多次,但是没有务实地学会。

代码:

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n, k;
    cin >> n >> k;
    vector<int> a(n), t(n);
    for (int i = 0; i < n; i++)
        cin >> a[i];
    int now = 0;
    for (int i = 0; i < n; i++)
        cin >> t[i], now += t[i] * a[i];
    int res = now;
    for (int i = 0; i < n;) {
        now += (!t[i]) * a[i];
        if (++i >= k) {
            res = max(res, now);
            now -= (!t[i - k]) * a[i - k];
        }
    }
    cout << res << endl;
    return 0;
}

今日头条2019校招笔试题

1. 求矩形的最大连通域

题目:

球场团队数与最大团队的人数

思路:

bfs,参考leetcode 200. Number of Islands。要注意的是输入,用逗号隔开,解决方法是每次读取一个数后,都调用cin.get()来清除逗号

代码:

void bfs(vector<vector<int>>& grid, int i, int j, int& num)

{

    if (i<0 || i>grid.size() - 1 || j<0 || j>grid[0].size() - 1 || grid[i][j] == 0)

        return;

    grid[i][j] = 0;

    ++num;

    bfs(grid, i - 1, j, num);

    bfs(grid, i + 1, j, num);

    bfs(grid, i, j - 1, num);

    bfs(grid, i, j + 1, num);

    bfs(grid, i - 1, j - 1, num);

    bfs(grid, i - 1, j + 1, num);

    bfs(grid, i + 1, j - 1, num);

    bfs(grid, i + 1, j + 1, num);

    return;

}


int main()

{

    int M, N;

    cin >> M;

    cin.get();

    cin >> N;

    vector<vector<int> > grid(M, vector<int>(N, 0));

    for (int i = 0; i < M; ++i)

    {

        for (int j = 0; j < N; ++j)

        {

            cin >> grid[i][j];

            cin.get();

        }

    }


    int num = 0, maxNum = 0;

    for (int i = 0; i != M; ++i)

    {

        for (int j = 0; j != N; ++j)

            if (grid[i][j] == 1)

            {

                int tmpMax = 0;

                bfs(grid, i, j, tmpMax);

                ++num;

                if (tmpMax > maxNum)

                    maxNum = tmpMax;

            }

    }

    cout << num << "," << maxNum << endl;

    return 0;

}

2. 区间合并

题目:

有多人给出区间,每个人给出多个,要求合并

思路:

先排序,排序规则是先左端点升序,相同时右端点升序。leetcode好像有做过类似的。。ps:这道题的分号逗号有点恶心,要单独处理下。

代码:

#include <string>

#include <vector>

#include <algorithm>

#include <iostream>


using namespace std;


struct Interval {

    long long start;

    long long end;

    Interval() : start(0), end(0) {}

    Interval(long long s, long long e) : start(s), end(e) {}

};


bool com(const Interval& a, const Interval& b)

{

    if (a.start != b.start)

        return a.start < b.start;

    if (a.end != b.end)

        return a.end < b.end;

    return false;

}


void SplitString(const string& s, vector<string>& v, const string& c)

{

    string::size_type pos1, pos2;

    pos2 = s.find(c);

    pos1 = 0;

    while (string::npos != pos2)

    {

        v.push_back(s.substr(pos1, pos2 - pos1));


        pos1 = pos2 + c.size();

        pos2 = s.find(c, pos1);

    }

    if (pos1 != s.length())

        v.push_back(s.substr(pos1));

}


int main()

{

    int m;

    cin >> m;


    vector<Interval> intervals;

    for (int i = 0; i < m; ++i)

    {

        string s;

        cin >> s;

        vector<string> v;

        SplitString(s, v, ";");

        int num = v.size();


        for (int j = 0; j < num; ++j)

        {

            vector<string> v0;

            SplitString(v[j], v0, ",");

            Interval x;

            x.start = stoi(v0[0]);

            x.end = stoi(v0[1]);

            intervals.push_back(x);

        }

    }


    sort(intervals.begin(), intervals.end(), com);

    long long len = intervals.size();

    vector<Interval> res;

    long long start(0);

    long long end(0);


    for (long long i = 0; i < len;)

    {

        start = intervals[i].start;

        end = intervals[i].end;

        long long j = i + 1;

        for (; j < len; ++j)

        {

            if (end < intervals[j].start)

                break;

            end = max(end, intervals[j].end);

        }

        res.push_back(Interval(start, end));

        i = j;

    }


    long long len2 = res.size();

    for (long long i = 0; i < len2; ++i)

    {

        cout << res[i].start << ',' << res[i].end;

        if (i != len2 - 1)

            cout << ';';

    }

}

搜狐2019校招笔试题

1. 亲密子串

题目:

兄弟串的定义:通过交换两个字符得到的字符串,如A=”abc”其兄弟串是“acb”,“bac”,”cba”。给定两个由小写字母组成的字符串A和B,判断他们是否为兄弟串,是就返回1,不是就返回0

思路:

基本的思路就是先看有没有重复的,有重复的就直接将相应的元素不输入到set中,如果不是重复的,就看两个是否相等,如果不相等就进行计数,看不相等的数字个数是否为2,不为2也不对,如果为2了,就将相应的存进去的下标提取出来,将两个字符串指定位置的字符进行比较,都相等就是对的。

代码:

class Solution {
public:
    bool buddyStrings(string A, string B) {
        if(A.empty() || B.empty()){
        return false;
    }
    if(A.size() != B.size()){
        return false;
    }
    vector<int> index;
    set<char> seen;
    bool res1=false;

    for(int i=0; i<A.size(); i++){
        if(seen.count(A[i])){
            res1 = true;
        }
        else{
            seen.insert(A[i]);
        }

        if(A[i] != B[i]){
            index.push_back(i);
        }
    }


    if(index.empty()){
        return res1;
    }
    else{
        if(index.size() != 2){
            return false;
        }
        return (A[index[0]] == B[index[1]] && A[index[1]] == B[index[0]]);
    }
    }
};

2. 计算移动次数

题目:

假设有一个无限长的x轴,你站在原点x=0处,要去往的目标点是x轴上的任意一个整数点,但是每次移动,只能向左或者向右,而且第N次移动就移动N的距离。现给定一个目标点target,要求为了到达目标点,移动最少次数。

思路:

这道题非常有意思,主要考察看问题的角度。这道题本质上就是一个递增序列改变加减号得到最终结果。所以可以这么来做,先将递增序列一直加,加到大于等于目标值,如果正好等于目标值,那么就直接等于那个值。如果大于那个目标值,就分两种情况考虑,如果超过的值和目标值的差值是偶数,就直接等于走的步数(因为只要调整某一步的值,就可以得到一个偶数的偏差值);如果超过的值和目标值的差值是奇数,就分两种一个是当前的步数是奇数,那么就不用凑出1(奇数和偶数的差值),如果当前的步数是偶数,那么就需要用下一步来凑出这个差值1

代码:

class Solution {
public:
    /**
     * @param target: the destination
     * @return: the minimum number of steps
     */
    int reachNumber(int target) {
        // Write your code here
        target = abs(target);

        int step = 1, pos = 0;
        while (pos < target) {
            pos += step;
            step++;
        }
        step--;
        if (pos == target) return step;
        pos -= target;
        if (pos % 2 == 0) {
            return step;
        } else if ((step + 1) % 2 == 1) {
            return step + 1;
        } else {
            return step + 2;
        }
    }
};

3. 比较版本号大小

题目:

比较两个版本号version1和version2,if version1>version2 return 1;if version1 < version2 return -1; other return 0;

思路:

版本号比对,还是比较简单的,开始的时候比较小数点之前的数字的大小相同的话,就将计数置为零,重新开始计数,如果输入的版本号后面不存在的话,可以直接往后遍历,因为长度不符合要求的字符串的计数直接就是0。

代码:

class Solution {
public:
    int compareVersion(string version1, string version2) {
        int n1 = version1.size(), n2 = version2.size();
        int i = 0, j = 0, d1 = 0, d2 = 0;
        while (i < n1 || j < n2) {
            while (i < n1 && version1[i] != '.') {
                d1 = d1 * 10 + version1[i++] - '0';
            }
            while (j < n2 && version2[j] != '.') {
                d2 = d2 * 10 + version2[j++] - '0';
            }
            if (d1 > d2) return 1;
            else if (d1 < d2) return -1;
            d1 = d2 = 0;
            ++i; ++j;
        }
        return 0;
    }
};
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页