秋招日寄|小红书笔试20240908编程题记录
第一题
进入一个充满挑战的高科技迷宫。这是一张由科技部最新研发的网格地图,每个格子都藏着秘密————它们内置了自动滑行带!
这些滑行带会让所有进入它们的机器人自动朝一个特定方向滑行。
具体来说,一张的网格地图,左上角为
,右下角为
,每个格子有一个滑行带,前进方向为
,分别表示左右上下四个方向前进。
如果第时刻,机器人位于
,
滑行带前进方向为
,则第
时刻机器人位于
。
如果第时刻,机器人位于
,
滑行带前进方向为
,则第
时刻机器人位于
。
如果第时刻,机器人位于
,
滑行带前进方向为
,则第
时刻机器人位于
。
如果第时刻,机器人位于
,
滑行带前进方向为
,则第
时刻机器人位于
。
机器人走出地图后就会毁坏,一个格子可以容纳多个机器人。
第时刻,每个位置都有一个机器人,问:第
时刻,地图上还剩下多少个机器人?
输入描述
第一行两个整数,表示地图大小。
接下来行,每行一个包含
个字符的字符串,表示每个格子滑行带的方向。
输出描述
输出一行一个整数,表示第时刻,地图上剩下机器人的数量。
样例1
输入
2 5 LRRLR UULLR
输出
6
答案
#include <iostream> #include <cstring> #include <algorithm> #include <vector> using namespace std; typedef pair<int, int> pii; const int N = 5e3 + 10; int n, m; int ans; string str[N]; int bps[N][N]; vector<pii> temp; pii check(int x, int y) { int a, b; if (str[x][y] == 'L') a = x, b = y - 1; else if (str[x][y] == 'R') a = x, b = y + 1; else if (str[x][y] == 'U') a = x - 1, b = y; else if (str[x][y] == 'D') a = x + 1, b = y; if (b == -1 || b == m || a == -1 || a == n) { for (int i = 0; i < temp.size(); i++) bps[temp[i].first][temp[i].second] = 2; return {-1, -1}; } else if (bps[a][b] == 1) { for (int i = 0; i < temp.size(); i++) bps[temp[i].first][temp[i].second] = 1, ans++; return {-1, -1}; } else if (bps[a][b] == 2) { for (int i = 0; i < temp.size(); i++) bps[temp[i].first][temp[i].second] = 2; return {-1, -1}; } else if (bps[a][b] == 3) { for (int i = 0; i < temp.size(); i++) bps[temp[i].first][temp[i].second] = 1, ans++; return {-1, -1}; } else return {a, b}; } void dfs(int x, int y) { temp.clear(); while (bps[x][y] == 0) { temp.push_back({x, y}); bps[x][y] = 3; pii tes = check(x, y); if (tes.first == -1) break; else { x = tes.first; y = tes.second; } } } int main() { cin >> n >> m; for (int i = 0; i < n; i++) cin >> str[i]; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (bps[i][j] == 0) dfs(i, j); } } cout << ans << endl; return 0; }
第二题
有一个长度为的数组
,他定义了一个函数
,即
(
)表示数组
在[
]这一段区间的区间和。
现在有一个重新任意排列数组的机会,想要最小化
,即最小化所有区间对于f的值之和,请你算算最小的这个值吧。
输入描述
第一行输入一个正整数(
)代表数组中元素的个数。
第二行输入个整数
(
)代表数组中的元素。
输出描述
在一行上输出一个整数,表示题中所求答案。
样例1
输入
3 1 2 3
输出
19
说明
重新排列为{},此时全部区间为[
]、[
]、[
]、[
]、[
]和[
]总和恰好为
,可以证明这是最小的。
样例2
输入
6 1 1 4 5 1 4
输出
128
答案
#include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { int n; cin >> n; vector<long long> arr(n); for (int i = 0; i < n; i++) { cin >> arr[i]; } sort(arr.begin(), arr.end()); long long sum1 = 0; for (int i = 0; i < n; i++) { long long contrib = (i + 1) * (long long)(n - i); sum1 += contrib * arr[n - i - 1]; } cout << sum1 << endl; return 0; }
第三题
定义(
)为x在二进制表示下的
个数,例如
,
,
。
定义为第一个比
大的数字
,使得
,例如
。
在首页有篇笔记,第
篇笔记的点赞数量为
,我们希望从中挑选出一些笔记,构造一个长度为
的精选队列
。在这里,精选队列满足:对于所有的
,都有
。
输入描述
第一行输入一个整数(
)。
第二行输入个整数
(
)。
输出描述
在一行上输出一个整数, 代表最长的精选队列的长度。
样例1
输入
5 1 4 2 5 3
输出
3
说明
可以构成几种精选队列,分别为:
其中最长的为
,长度为
样例2
输入
6 1 1 4 5 1 4
输出
128
答案
#include <iostream> #include <vector> #include <algorithm> #include <bitset> #include <set> using namespace std; int g(int x) { string s = bitset<32>(x).to_string(); int firstOne = s.find('1'); if (firstOne == string::npos) return 0; int firstZero = s.rfind('0', firstOne); if (firstZero == string::npos) firstZero = -1; int onesToMove = firstOne - firstZero - 1; string newS = string(32, '0'); newS[firstZero + 1] = '1'; fill(newS.end() - onesToMove, newS.end(), '1'); return bitset<32>(newS).to_ulong(); } int solve(vector<int>& a) { sort(a.begin(), a.end()); set<int> st(a.begin(), a.end()); int ans = 0; for (int x : st) { int cnt = 0; while (st.count(x)) { cnt++; st.erase(x); x = g(x); } ans = max(ans, cnt); } return ans; } int main() { int n; cin >> n; vector<int> a(n); for (int i = 0; i < n; i++) { cin >> a[i]; } cout << solve(a) << endl; return 0; }#通信硬件人笔面经互助#
本人在秋招过程中的一些笔试和面经,尽可能的结构化、系统化的整理了,有些细节可能记不太清,大家可以随便提问,肯定知无不言言无不尽!