tb的区间问题
题目描述
登录—专业IT笔试面试备考平台_牛客网
运行代码
#include <iostream>
#include <climits>
using namespace std;
int main() {
int n, k;
cin >> n >> k;
int arr[50000];
for (int i = 0; i < n; ++i) {
cin >> arr[i];
}
int sum = 0, maxSum = INT_MIN;
int jud = n - k;
for (int j = 0; j < n; ++j) {
sum = 0;
for (int i = 0; i < jud; ++i) {
sum += arr[i + j];
}
maxSum = max(maxSum, sum);
}
cout << maxSum << endl;
return 0;
}
代码思路
- 首先确定一个观察窗口的大小,这里用变量
jud
表示,其值为n - k
,即最终剩余的元素个数。 - 然后通过两层循环来遍历数组:
- 外层循环
for (int j = 0; j < n; ++j)
用于确定起始位置,每次循环都会重新计算一个从当前起始位置开始长度为jud
的子数组的和。 - 内层循环
for (int i = 0; i < jud; ++i)
用于计算从当前起始位置j
开始长度为jud
的子数组的和,将子数组中的元素累加到sum
变量中。
- 外层循环
- 在每次内层循环结束后,更新
Maxsum
的值,使其始终保持为当前找到的最大子数组和。具体更新方式为Maxsum = (sum > Maxsum)? sum : Maxsum;
,即如果当前子数组和sum
大于之前找到的最大子数组和Maxsum
,则更新Maxsum
为sum
,否则保持Maxsum
不变。 - 最后输出
Maxsum
,即为经过k
次操作后剩余数组元素之和的最大值。
tb的数数问题
题目描述
登录—专业IT笔试面试备考平台_牛客网
运行代码
#include <iostream>
#include <vector>
const int MAXN = 1000005;
const int MOD = 998244353;
using namespace std;
int n;
vector<bool> vis(MAXN, false);
vector<bool> isGood(MAXN, true);
int ans = 0;
void solve() {
cin >> n;
for (int i = 0; i < n; ++i) {
int x;
cin >> x;
vis[x] = true;
}
if (vis[1]) {
for (int i = 1; i <= MAXN - 1; ++i) {
if (isGood[i] && vis[i]) {
ans++;
} else {
for (int j = 2; i * j <= MAXN - 1; ++j) {
isGood[i * j] = false;
}
}
}
}
cout << ans << endl;
}
int main() {
solve();
return 0;
}
代码思路
-
首先定义一些常量和变量:
MAXN
表示可能的最大数字范围。MOD
在这段代码中似乎未被实际使用。n
表示集合的大小。vis
是一个布尔类型的向量,用于标记输入集合中出现的数字。isGood
是一个布尔类型的向量,用于标记每个数字是否可能是 “好的”。ans
用于统计 “好的” 数字的个数。
-
读取输入集合:
- 通过
cin >> n
读取集合的大小。 - 然后使用一个循环读取集合中的每个数字,并将其在
vis
向量中对应的位置标记为true
。
- 通过
-
检查每个数字是否是 “好的”:
- 首先检查数字
1
是否在集合中。如果数字1
在集合中,才进行后续的判断。 - 对于从
1
到MAXN - 1
的每个数字i
:- 如果
isGood[i]
为true
且vis[i]
也为true
,说明数字i
是 “好的”,将ans
加一。 - 如果数字
i
不是 “好的”,则对于所有i
的倍数i * j
(其中j >= 2
且i * j <= MAXN - 1
),将isGood[i * j]
标记为false
,因为如果i
不是 “好的”,那么它的倍数也不可能是 “好的”。
- 如果
- 首先检查数字
-
输出结果:最后输出
ans
,即 “好的” 数字的个数。
tb的排列问题
题目描述
登录—专业IT笔试面试备考平台_牛客网
运行代码
#include <iostream>
#include <vector>
const int mod = 998244353;
using namespace std;
void solve() {
int n, w;
cin >> n >> w;
vector<int> b(n + 1);
vector<int> P(n + 1, 0);
vector<int> pre(n + 1, 0);
for (int i = 1; i <= n; ++i) {
int x;
cin >> x;
if (x!= -1) P[x] = i;
pre[i] = pre[i - 1] + (x == -1? 1 : 0);
}
for (int i = 1; i <= n; ++i) cin >> b[i];
long long ans = 1;
int cnt = 0;
for (int i = 1; i <= n; ++i) {
int x = b[i];
if (P[x]) {
if (P[x] > (i + w)) {
cout << "0\n";
return;
}
continue;
}
ans *= (pre[min(n, i + w)] - cnt);
ans %= mod;
cnt++;
}
cout << ans << '\n';
}
int main() {
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
代码思路
-
输入与预处理
- 首先读取输入的
n
和w
,分别表示排列的长度和幸运数字。 - 然后创建三个向量:
b
用于存储给定的排列B
;P
用于记录已知元素在最终可能的完整排列中的位置;pre
用于记录从开始位置到当前位置的未知元素个数的前缀和。 - 遍历输入的部分已知排列
A
,如果某个位置上的元素不是 -1,则将该元素在P
中的对应位置记录为当前遍历的位置i
。同时,计算pre
向量,统计每个位置之前的未知元素个数。
- 首先读取输入的
-
主要计算过程
- 初始化答案
ans
为 1,以及计数器cnt
为 0。 - 遍历给定的排列
B
:- 如果当前元素在
P
中有记录,表示这个元素在部分已知排列A
中是确定的位置。如果这个确定的位置大于当前位置i
加上幸运数字w
,说明无法得到这样的排列,输出 0 并返回。否则,继续处理下一个元素。 - 如果当前元素在
P
中没有记录,表示这个位置在部分已知排列A
中是未知的。此时,答案ans
乘以在区间[i, min(i+w, n)]
内的未知元素个数,即pre[min(n, i + w)] - cnt
。然后更新计数器cnt
,表示已经处理了一个未知位置。
- 如果当前元素在
- 初始化答案
-
输出结果:最后输出答案
ans
,即为可能的完整排列A
的数量对998244353
取模后的结果。