深信服2025届全球校招研发笔试-C卷(AK)

前面14个填空题

T1

已知 子数组 定义为原数组中的一个连续子序列。现给定一个正整数数组 arr,请计算该数组内所有可能的奇数长度子数组的数值之和。

输入描述

输入一个正整数数组arr

输出描述

所有可能的奇数长度子数组的和

示例 1
输入

1,4,2,5,3

输出

58

说明

解释:所有奇数长度子数组和它们的和为:
[1] = 1
[4] = 4
[2] = 2
[5] = 5
[3] = 3
[1,4,2] = 7
[4,2,5] = 11
[2,5,3] = 10
[1,4,2,5,3] = 15
我们将所有值求和得到1 + 4 + 2 + 5 + 3 + 7 + 11 + 10 + 15 = 58

C++实现代码

#include <bits/stdc++.h>
#include <iostream>
#include <string> 
#include <sstream>

using namespace std;

int main() {
	string input;
	vector<int> v;
	getline(cin, input);

	stringstream ss(input);
	string item;
	while (getline(ss, item, ',')) {
		v.push_back(stoi(item));
	}

	long long ans = 0;
	int n = v.size();
	for (int i = 0; i < n; i++) {
		long long cur = 0;
		int cnt = 0;
		for (int j = i; j < n; j++) {
			cur += v[j];
			cnt += 1;
			if (cnt % 2) {
				ans += cur;
			}
		}
	}
	cout << ans << endl;
	return 0;
}

在这里插入图片描述

T2

平台运行过程中出现异常时一般会将信息记录在后台日志文件中,定位问题时通常使用关键字进行过滤。正则表达式具备很强大的文本匹配功能,能够快速高效地处理文本。常见元字符为:

^:匹配字符串开头。
$:匹配字符串结尾。
.:匹配任意字符。
*:匹配前面的字符零次或多次。
+:匹配前面的字符一次或多次。
?:匹配前面的字符零次或一次。

给定一个输入字符串s和一个字符模式p,s和p的长度均在100以内,要求实现一个支持’.‘和’*'的正则表达式匹配。字符模式必须能够完全匹配输入字符串。

如果匹配成功返回1,匹配失败返回0

请设计一个时间复杂度为 O(mn)或更优的算法来解决这个问题。如果使用内置正则库得0分。

输入描述

第一行输入为字符串s
第二行输入为字符模式p

输出描述

如果匹配成功返回1,匹配失败返回0

示例 1

输入

aaa
a*

输出

1

说明

通配符*可以匹配aa

示例 2

输入

abaa
ab*a

输出

0

说明

通配符*匹配前面的字符零次或多次,由于前面的字符是b,无法匹配a

示例 3

输入

abaa
ab.a

输出

1

说明

通配符.可以匹配任意字符,因此能够匹配a

C++实现代码

#include <bits/stdc++.h>
#include <iostream>

using namespace std;

bool isMatch(string s, string p) {
    int m = s.size(), n = p.size();
    vector<vector<bool>> dp(m + 1, vector<bool>(n + 1, false));
    dp[0][0] = true;
    for (int j = 1; j <= n; j++) {
        if (p[j - 1] == '*') {
            // s为空字符串的时候, *匹配0个元素, 例如"a*" = ""
            dp[0][j] = dp[0][j - 2];
        }
    }
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            if (s[i - 1] == p[j - 1] || p[j - 1] == '.') {
                dp[i][j] = dp[i - 1][j - 1];
            }
            else if (p[j - 1] == '*') {
                // *匹配0次
                if (s[i - 1] != p[j - 2] && p[j - 2] != '.') {
                    dp[i][j] = dp[i][j - 2];
                    // *匹配多次
                }
                else {
                    dp[i][j] = dp[i][j - 2] || dp[i - 1][j];
                }
            }
        }
    }
    return dp[m][n];
}

int main() {
    string s, p;
    cin >> s >> p;
    if (isMatch(s, p)) {
        cout << 1 << endl;
    }
    else {
        cout << 0 << endl;
    }
    return 0;
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

T3

给定存在 N个元组的集合,每个元组里面的值为(等级,价格),等级和价格都是非负整数。在集合中选取数量大于0小于等于N的元组,要求这些元组的等级差不能超过x,并且它们的价格之和最大。最后输出最大的价格

输入描述

第一行包含两个整数 N 和 x (1 ≤ n ≤ 105,1 ≤ x ≤ 1010) —— 分别是给定的元组集合的数量和等级差。
接下来的 N 行是元组的具体数值,每一行为一个元组的两个值,等级和价格,数字之间用空格隔开

输出描述

输出选取的元组最大的价格之和

示例 1

输入

4 2
0 14
3 16
8 9
10 18

输出

27

说明
总共有4个元组,限制选取的元组等级差为2,那么只能选第三和第四个,或者只选一个。对比这几种选组,价格之和最高的是选第三和第四个元组,结果为27。

C++实现代码

#include <bits/stdc++.h>
#include <iostream>

using namespace std;

int main() {
	int N;
	long long x;
	cin >> N >> x;
	vector<vector<long long>> v(N, vector<long long>(2));
	for (int i = 0; i < N; i++) {
		cin >> v[i][0] >> v[i][1];
	}

	sort(v.begin(), v.end());
	long long ans = 0;
	int i = 0, j = 0;
	long long cur = v[0][1];
	while (j < N) {
		if (v[j][0] - v[i][0] <= x) {
			ans = max(ans, cur);
			j++;
			if (j < N) {
				cur += v[j][1];
			}
		}
		else {
			cur -= v[i][1];
			i++;
		}
	}
	cout << ans << endl;
	return 0;
}

在这里插入图片描述

T4

小明正在一个由m x n的单元格组成的游戏地图上寻找金币,地图由一个二维整数数组 grid 表示。每个 grid[i][j] 都表示地图上单元格 (i, j) 的金币数量。如果 grid[i][j]是 0,表示这个单元格没有金币。如果 grid[i][j]是正数,表示这个单元格有grid[i][j] 个金币。如果 grid[i][j]是-1,表示这个单元格是不可到达的区域。小明的起始位置是左上角,也就是点(0,0),并且每次可以向上、下、左、右四个方向移动,但不能移出游戏地图。小明有一个特殊的技能: 他可以使用这个技能将一个不可到达的区域(-1的单元格)变为可达区域,但是他只能使用一次这个技能。使用技能后,不可到达的区域会变成0,也就是没有金币但是可以通过。
你的任务是帮助小明计算,他最多可以收集多少个金币。

输入描述

m,n范围为[0,100]
grid[i][j]值范围为[-1,5],其中0≤i≤m,0≤j≤n

输出描述

输出收集金币数

示例 1

输入

[1,-1]
[1,1]

输出

2

说明

输入一个2*2的二维数组,小明将grid [0][1](或grid[1][0])的-1变成0则可收集到价值2金币,故输出2

示例2

输入

[-1]

输出

0

说明

输入一个1*1的二维数组,小明无论是否使用技能都无法获得金币,故输出0

C++实现代码

#include <bits/stdc++.h>
#include <iostream>
#include <string>
#include <sstream>
#include <deque>

using namespace std;

int main() {
	vector<vector<int>> v;
	string line;
	while (getline(cin, line) && !line.empty()) {
		istringstream iss(line.substr(1, line.size() - 2));
		string token;
		vector<int> row;
		while (getline(iss, token, ',')) {
			if (!token.empty()) {
				row.push_back(stoi(token));
			}
		}
		v.push_back(row);
	}

	deque<pair<int, int>> dq;
	vector<vector<int>> vis;
	int m, n;

	m = v.size();
	n = v[0].size();

	vis.assign(m, vector<int>(n, 0));

	function<int(void)> func = [&](void){
		if (v[0][0] == -1) {
			return 0;
		}
		dq.clear();
		vis.assign(m, vector<int>(n, 0));
		dq.push_back({ 0, 0 });
		vis[0][0] = 1;
		// 下上右左
		int dx[] = { 0, 0, 1, -1 };
		int dy[] = { 1, -1, 0, 0 };
		int ans = 0;
		while (!dq.empty()) {
			auto [x, y] = dq.front();
			dq.pop_front();
			ans += v[x][y];
			for (int i = 0; i < 4; i++) {
				int nx = x + dx[i], ny = y + dy[i];
				if (nx >= 0 && nx < n && ny >= 0 && ny < m && v[nx][ny] >= 0 && !vis[nx][ny]) {
					vis[nx][ny] = 1;
					dq.push_back({ nx, ny });
				}
			}
		}
		return ans;
	};

	int ans = func();
	for (int i = 0; i < m; i++) {
		for (int j = 0; j < n; j++) {
			if (v[i][j] == -1) {
				v[i][j] = 0;
				ans = max(ans, func());
				v[i][j] = -1;
			}
		}
	}
	cout << ans << endl;
	return 0;
}

在这里插入图片描述
之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值