前言
每次竞赛总会找到一些细小的,以前没见过的错误,或者想到一些还不错的解法,于是通通记录在这。
毕竟有的错会导致WA,相当于直接多做了5分钟,还是很不划算的。
第348场竞赛
这题的难点是要想到逆序处理。思路是从后往前覆盖,已经处理过的行或列就不用再重复处理。我当时的想法是用哈希表记录对应的一组操作,来让其不会重复
使用类型:unordered_set<pair<int, int>>
pair记录对应的 type 和操作的行号或列号
可这里的坑在于 pair 需要自定义哈希函数,pair 没有默认定义的哈希函数。
哈希函数的指定只需让其每一个元素唯一即可,这道题的数据是 1e4,所以据此构造出哈希函数。
struct pair_hash {
template<class T1, class T2>
size_t operator()(const pair<T1, T2> &data) const {
return data.first * 1e4 + data.second;
}
};
class Solution {
public:
long long matrixSumQueries(int n, vector<vector<int>>& queries) {
unordered_set<pair<int, int>, pair_hash> operations;
vector<int> record;
int i, m = queries.size();
for (i = m - 1; i >= 0; --i) {
if (operations.count({queries[i][0], queries[i][1]}) == 0) {
operations.insert({queries[i][0], queries[i][1]});
record.emplace_back(i);
}
}
// operations 过滤重复操作
// record 记录过滤后的操作
// 并且 record 的前面对应的是 queries 里后面的操作
int j;
long long ans = 0;
int row = n, colone = n;
// row 和 colone 记录剩余的未填的行或列
for (j = 0; j < record.size(); ++j) {
if (row > 0 && queries[record[j]][0] == 0) {
// 还有多少剩余的列可以填上这个数
ans += colone * queries[record[j]][2];
--row;
} else if (colone > 0 && queries[record[j]][0] == 1) {
// 还有多少剩余的行可以填上这个数
ans += row * queries[record[j]][2];
--colone;
}
}
return ans;
}
};
第349场竞赛
- long 的最大值:LONG_MAX
- longlong 的最大值: LLONG_MAX
- int 和 long long 在做乘法的时候乘数在int范围内,如果乘积超了int,也需要将乘数定义为long long
P3收集巧克力
这题的想法是遍历执行操作的次数,从 1 到 n
注意复杂度 n 仅
1
0
3
10^3
103
使用二维数组记录下当前位置经过 k 次操作后的最小值
pool[i][k] 即表示经过 k 次操作 下标 i 位置上的最小值,随后我们遍历所有次数计算值即可
class Solution {
public:
long long minCost(vector<int>& nums, int x) {
int i, j, n = nums.size();
vector<vector<int>> pool(n, vector<int>(n));
for (i = 0; i < n; ++i) {
int mmin = nums[i];
int k = 0;
pool[i][k] = nums[i];
for (j = i - 1; j >= 0; --j) {
pool[i][++k] = mmin = min(mmin, nums[j]);
//cout << pool[i][k] << " ";
}
for (j = n - 1; j > i; --j) {
pool[i][++k] = mmin = min(mmin, nums[j]);
//cout << pool[i][k] << " ";
}
//cout << endl;
}
long long res = LLONG_MAX;
for (i = 0; i < n; ++i) {
// 使用 i 次操作带来的成本 i * x
long long ans = (long long)i * x;
for (j = 0; j < n; ++j) {
// 加上每个位置上 i 次操作对应的最小值
ans += pool[j][i];
}
res = min(res, ans);
}
return res;
}
};
这题的难点在于想到对次数进行遍历,从直觉上来说其代价似乎较为高昂,然而借用二维数组,时间复杂度控制在了 1 0 6 10^6 106量级