这次题目其实挺简单的,做了 50 多分钟就做完了一轮,但是三四题没全过,结果回去改第三题改了一小时没 AC。。。
1. s 重排最多包含几个 acbcca (100%)
字符串 s 只包含小写字母,可以任意重排,问重拍后 acbcca 最多出现几次?
示例:
- 重排后
acbcca包含一个acbcca - 重排后
acbcc**a**cbcca包含两个acbcca - 重排后
acbcc**a**cbcc**a**cbcca包含三个acbcca
规律:
acbcca 次数 |
1 | 2 | 3 | … | n |
|---|---|---|---|---|---|
所需 a 个数 |
2 | 3 | 4 | n+1 | |
所需 b 个数 |
1 | 2 | 3 | n | |
所需 c 个数 |
3 | 6 | 9 | 3n |
因此,统计字符串 s 中包含的 a、b、c 个数,结果就是 min(a 个数 - 1,b 个数, c 个数 / 3)
2. 见面的最小路程差 (100%)
给定一个递增数组,代表 n 个点,要求找到一个点,使得从位置 1 到该点的距离 和 位置 n 到该点的距离之差最小
直接遍历每个点即可,分别计算每个点到两端的距离,再计算距离之差,并更新全局最小值
3. 和为 7 的倍数的最大值 (64%)
从 n 个数中选择任意个数,要求和为 7 的倍数,求和的最大值
解法:
- 递归回溯:超时,只能过 36%
- 动态规划:(笔试的时候边界和状态转移没考虑对,只过了 64%)
- 动态规划数组
dp:dp[i][j]代表只从前i个数里进行挑选数字,和对7取余为j的最大值 - 状态转移方程:
dp[i][j] = max(dp[i][j], dp[i - 1][j], dp[i - 1][preIdx] + nums[i - 1])dp[i - 1][j]代表不取第i个数,即只从前i - 1数里挑选数字,和对7取余为j的最大值dp[i - 1][preIdx] + nums[i - 1]代表取第i个数的最大值。取了第i个数(nums[i - 1]),要让和模 7 为j,则从前i - 1个数中选择的数字只和模7应为j - nums[i - 1] % 7,为了避免出现负数的情况,所以再+ 7再模7,即preIdx = ((j - nums[i - 1]) % 7 + 7) % 7
- 初始化:
- 动态规划数组
int main()
{
int n;
cin >> n;
vector
// vector<vector<int>> dp(n + 1, vector<int>(7, -0x3f3f3f3f));vector<vector<long long>> dp(n + 1, vector<long long>(7, INT_MIN));dp[0][0] = 0;for(int i = 1; i <= n; ++i){for(int j = 0; j < 7; ++j){dp[i][j] = max(dp[i][j], dp[i - 1][j]);int preIdx = ((j - nums[i - 1]) % 7 + 7) % 7;dp[i][j] = max(dp[i][j], dp[i - 1][preIdx] + nums[i - 1]);}}cout << dp[n][0] << endl;return 0;
}
<a name="zfo94"></a># 4. 奇数长区间中位数的和 (82%)给定一个长为 n 的数组,求所有长度为奇数的区间的中位数之和。中位数是区间排序后最中间的数。解法:1. 暴力:会超时,过了 82%```cpp#include <iostream>#include <vector>#include <algorithm>using namespace std;int main(){int n;cin >> n;vector<int> nums(n);for(int i = 0; i < n; ++i)cin >> nums[i];int result = 0;for(int len = 1; len <= n; len = len + 2) // 遍历所有奇数长的区间长度{for(int i = 0; i + len <= n; ++i) // 遍历区间起点{// 将当前区间的数存储到 temp 数组,排序,取中间的数就是中位数vector<int> temp(len);for(int j = i; j < i + len; ++j)temp[j - i] = nums[j];sort(temp.begin(), temp.end());result += temp[len / 2];}}cout << result << endl;return 0;}
- 参考:leetcode 480. 滑动窗口中位数,leetcode 求的是固定窗口长度 k。滑动窗口,求每个窗口的中位数。而本题,只需要外面再套一层循环,遍历窗口长度 k 即可(k 为奇数)
