【牛客网】字节跳动2019春招研发部分编程题汇总

1-万万没想到之聪明的编辑

解题思路

此题的编辑规则如下

  1. 三个同样的字母连在一起,一定是拼写错误,去掉一个的就好啦:比如 helllo -> hello
  2. 两对一样的字母(AABB型)连在一起,一定是拼写错误,去掉第二对的一个字母就好啦:比如 helloo -> hello
  3. 上面的规则优先“从左到右”匹配,即如果是AABBCC,虽然AABB和BBCC都是错误拼写,应该优先考虑修复AABB,结果为AABCC

从题目可以看出,本题的规则实际上只有两个,1和2,1是指连续3个同样的字母,则去掉一个;
2是指两对一样的字母,则去掉第二对的一个字母。第3条规则告诉我们规则是从左往右匹配,因此每次我们去掉的字母都将是形成这种规则的最后一个字母。
所以对给定的字符串,先对其执行规则1,再执行规则2。

代码

#include
#include
using namespace std;
int main() {
     
	int n;
	cin >> n;
	while (n--) {
     
		string s;
		cin >> s;
		//规则1
		for (int i = 2; i < s.length(); i++) {
     
			if (s[i] == s[i - 1] && s[i - 1] == s[i - 2]) {
     
				s.erase(i, 1);//满足规则1,删除一个该字符
				i--;
				if (s.length() < 3) break;
			}
		}
		//规则2
		for (int i = 3; i < s.length(); i++) {
     
			if (s[i] == s[i - 1] && s[i - 2] == s[i - 3]) {
     
				s.erase(i, 1);//满足规则2,删除一个该字符
				i--;
				if (s.length() < 3)break;
			}
		}
		cout << s << endl;
	}
}

2-万万没想到之抓捕孔连顺

解题思路

参考自该博客

题目的意思,就是给定一系列已排序的数,从这些数中任选三个数,使其满足最大和最小的数差值小于等于给定值。

我觉得下面该blog的思想有些不对,如果打印出具体的组合将是错误的结果,但是由于其计算组合数的数目是对的,因此产生了正确的结果;
例如下面的输入

输入: 
4 3
1 2 3 4

对于blog中的思想,其将产生的组合分别为:

#此时left=0,right=2
1 2 3 
#此时left=0,right=3
1 2 3
1 2 4
1 3 4 

可以看出组合数量是对的,但真正的组合并没有求对,在right=3时,发生了重复,多了一组,而这组应该为2 3 4

代码

#include
#include
using namespace std;
long long C(long long n) {
     //计算Cn2的值
	return (n - 1) * n / 2;
}
int main() {
     
	int N,D;
	while (cin >> N >> D) {
     
		vector<int> arr(N);
		for (int i = 0; i < N; i++) {
     
			cin >> arr[i];
		}
		//固定p_left,移动p_right,如果满足两者之差<=D,则从[p_left+1,p_right]中选择两个,即为存在的个数
		long p_left = 0,p_right =2,count = 0;
		for (; p_right < N;p_right++) {
     
			while (arr[p_right] - arr[p_left] > D) {
     
				p_left++;
			}
			count += C(p_right - p_left);
		}
		cout<<count%99997867;
	}
	return 0;
}

4-特征提取

解题思路

使用map, pair>;//key-特征(x,y)-value-(起点帧的序号,特征计数)
遍历每个帧,加入新特征或者更新已存在特征的帧起点,特征计数
1、如果该特征不存在,则添加该特征到map
2、如果该特征存在
通过判断(当前帧号==特征起点帧号+特征计数),相等表示连续
(1)如果该特征是连续的,特征计数+1;
(2)如果该特征是不连续的,更新特征起点为当前帧号,特征计数+1;

参考自题解

代码

#include
#include
#include
using namespace std;
int main() {
     
	int n;
	cin >> n;//样例数
	for (int k = 0; k < n; k++) {
     
		int m;//帧数
		cin >> m;
		map<pair<int, int>, pair<int, int>> mp;
		int maxLen = 1;
		for (int i = 0; i < m; i++) {
     
			int t;//本帧特征数
			cin >> t;
			for (int j = 0; j < t; j++) {
     
				int x, y;
				pair<int, int> p;
				cin >> p.first >> p.second;
				//判断该帧是否存在
				//不存在
				if (mp.find(p) == mp.end()) {
     //原本无该特征,添加该特征
					mp[p].first = i;//该帧的起点帧
					mp[p].second = 1;//该特征初始计数为1
				}
				//存在
				else {
     
					//连续
					if (i == mp[p].second + mp[p].first) {
     
						mp[p].second++;
						maxLen = max(maxLen, mp[p].second);
					}
					//不连续
					else {
     
						mp[p].first = i;//更新起始帧号
						mp[p].second = 1;//更新计数
					}
				}
			}
		}
		cout << maxLen << endl;
	}
	return 0;
}

你可能感兴趣的:(【魂】算法,秋招笔试,算法,C++,秋招)