今日头条2017实习生笔试题解

Prob 1. 找出函数的最宽尖峰

题意:求给定数列 A 中先升后降的最长连续子序列,要求 O(n)。

思路:左右各做一遍最长上升子串,求最大和即可。

#include <iostream>
#include <vector>
using namespace std;


int main()
{
	int n;
	cin >> n;
	vector<int> nums(n, 0);
	for (int i = 0; i < n; ++i)
		cin >> nums[i];

	vector<int> left(n, 0);
	vector<int> right(n, 0);

	for (int i = 1; i < n; ++i)
	{
		if (nums[i] > nums[i - 1])
			left[i] = left[i - 1] + 1;
	}
	for (int i = n - 2; i >= 0; --i)
	{
		if (nums[i] > nums[i + 1])
			right[i] = right[i + 1] + 1;
	}

	int max = 0, l = -1, r = -1;
	for (int i = 0; i < n; ++i)
	{
		if (left[i] > 0 && right[i] > 0 && left[i] + right[i] > max)
		{
			max = left[i] + right[i];
			l = i - left[i];
			r = i + right[i];
		}
	}

	cout << l << " " << r << endl;
	
	
	return 0;
}


Prob 2. Paragraph

题意:给定一个英文段落(包含 n 个句子)和 m 次查询,每次给定一个句子,求段落中相同单词数量最多的句子。各个英文句子不包含标点,大小写不敏感。

思路:用set或者hashset解决,体力活。

#include <iostream>
#include <string>
#include <set>
#include <unordered_set>
#include <vector>
#include <algorithm>
using namespace std;


int main()
{
	int n, m;
	char cc;
	cin >> n >> m;
	vector<unordered_set<string>> setence(0);
	vector<string> vec(0);

	string str;
	getline(cin, str);
	for (int k = 0; k < n; ++k)
	{
		
		getline(cin, str);

		vec.push_back(str);

		unordered_set<string> temp;
		temp.clear();

		string word = "";
		for (int i = 0; i < str.size(); ++i)
		{
			if (str[i] == ' ')
			{
				if (word.size() > 0)
				{
					transform(word.begin(), word.end(), word.begin(), ::tolower);
					temp.insert(word);
				}
				word = "";
			}
			else if (str[i] != ' ')
			{
				word += str[i];
			}
		}
		if (word.size() > 0)
		{
			transform(word.begin(), word.end(), word.begin(), ::tolower);
			temp.insert(word);
		}
		setence.push_back(temp);
	}

	for (int k = 0; k < m; ++k)
	{
		getline(cin, str);

	
		unordered_set<string> temp;
		temp.clear();

		string word = "";
		for (int i = 0; i < str.size(); ++i)
		{
			if (str[i] == ' ')
			{
				if (word.size() > 0)
				{
					transform(word.begin(), word.end(), word.begin(), ::tolower);
					temp.insert(word);
				}
				word = "";
			}
			else if (str[i] != ' ')
			{
				word += str[i];
			}
		}
		if (word.size() > 0)
		{
			transform(word.begin(), word.end(), word.begin(), ::tolower);
			temp.insert(word);
		}
		word = "";

		int index = 0, max = 0;
		for (int i = 0; i < n; ++i)
		{
			int count = 0;
			for (auto it = temp.begin(); it != temp.end(); ++it)
			{
				if (setence[i].find(*it) != setence[i].end())
					++count;
			}
			if (count > max)
			{
				max = count;
				index = i;
			}
		}

		cout << vec[index] << endl;
	}

	

	return 0;
}


Prob. 3 绘制括号序列

题意:给定一个合法的括号序列,以字符矩阵的形式翻转后输出。

思路:先遍历一遍统计每个括号在第几层,然后模拟,体力活。

有个坑,看图,红框中的边上不应该有“|”。


#include <iostream>
#include <string>
#include <vector>
using namespace std;


int main()
{
	string str;
	cin >> str;
	if (str.size() == 0)
		return 0;
	vector<int> level(str.size(), 0);
	int l = 0;
	int maxL = 0;
	for (int i = 0; i < str.size(); ++i)
	{
		if (str[i] == '[')
		{
			++l;
			level[i] = l;
			if (l > maxL)
				maxL = l;
		}
		if (str[i] == ']')
		{
			level[i] = l;
			--l;
		}
	}
	for (int i = 0; i < str.size(); ++i)
		level[i] = maxL - level[i];


	--maxL;
	for (int i = 0; i < str.size(); ++i)
	{
		if (str[i] == '[')
		{
			if (level[i] == maxL || level[i] == level[i-1])
			{
				for (int j = 0; j < (2 * maxL - 2 * level[i]) / 2; ++j)
					cout << ' ';
				cout << '+';
				for (int k = 0; k < 2 * level[i] + 1; ++k)
					cout << '-';
				cout << '+';
				for (int j = 0; j < (2 * maxL - 2 * level[i]) / 2; ++j)
					cout << ' ';
				cout << endl;
			}
			else
			{
				for (int j = 0; j < (2 * maxL - 2 * level[i] - 2)/2; ++j)
					cout << ' ';
				cout << "|+";
				for (int j = 0; j < (2 * level[i] + 1); ++j)
					cout << '-';
				cout << "+|";
				for (int j = 0; j < (2 * maxL - 2 * level[i] - 2) / 2; ++j)
					cout << ' ';
				cout << endl;
			}


			if (level[i] == level[i + 1])
			{
				for (int j = 0; j < (2 * maxL - 2 * level[i]) / 2; ++j)
					cout << " ";
				cout << "|";
				for (int j = 0; j < 2 * level[i] + 1; ++j)
					cout << " ";
				cout << "|";
				for (int j = 0; j < (2 * maxL - 2 * level[i]) / 2; ++j)
					cout << " ";
				cout << endl;

				for (int j = 0; j < 2 * maxL + 3; ++j)
					cout << " ";
				cout << endl;
			}
			
		}
		else if (str[i] == ']')
		{
			if (level[i] == level[i - 1])
			{
				for (int j = 0; j < (2 * maxL - 2 * level[i]) / 2; ++j)
					cout << " ";
				cout << "|";
				for (int j = 0; j < 2 * level[i] + 1; ++j)
					cout << " ";
				cout << "|";
				for (int j = 0; j < (2 * maxL - 2 * level[i]) / 2; ++j)
					cout << " ";
				cout << endl;
			}

			if (level[i] == maxL || level[i] == level[i+1])
			{
				for (int j = 0; j < (2 * maxL - 2 * level[i]) / 2; ++j)
					cout << ' ';
				cout << '+';
				for (int k = 0; k < 2 * level[i] + 1; ++k)
					cout << '-';
				cout << '+';
				for (int j = 0; j < (2 * maxL - 2 * level[i]) / 2; ++j)
					cout << ' ';
				cout << endl;
			}
			else
			{
				for (int j = 0; j < (2 * maxL - 2 * level[i] - 2) / 2; ++j)
					cout << ' ';
				cout << "|+";
				for (int j = 0; j < (2 * level[i] + 1); ++j)
					cout << '-';
				cout << "+|";
				cout << endl;
			}
		}
	}

	return 0;
}


Prob. 4 数列

题意:给定两个数列 A 和 B 以及 q 组查询 (x, y),每次求满足 A[i] >= x 且 B[i] >= y 这样的 i 的数量。

思路:将数列A和B,以及查询q,都根据x排序(y也行),然后按x序查询,对y来说就只有插入,没有删除了,用平衡树可解。

代码:暂无,笔试的时候一直在第三题那个坑里,第四题没做,找机会再补吧。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值