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

网易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;
    }
};
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值