AcWing第63场周赛
第一题:4503. 数对数量
分析:因为本题数据范围较小,所以可以直接枚举。
代码:
#include<iostream>
int a,b,n;
using namespace std;
int main()
{
int cnt = 0;
cin >> a >> b >> n;
for(int i = 0;i <= a;i ++){
for(int j = 0;j <= b; j ++){
if(i + j == n)cnt ++;
}
}
cout << cnt;
return 0;
}
第二题:4504. 字符串消除
分析: 任意次序取相邻做消除,最后结果是一样的。首先统计消除操作的数目,发现 如果是偶数,那么先手必输。可以利用栈的数据结构, 一出现成对就删除。
代码:
#include<iostream>
#include<cstring>
using namespace std;
int main() {
string s;
string stk;
cin >> s;
int ans = 0;
for (auto &c : s) {
if (stk.back() == c) {
ans++;
stk.pop_back();
} else {
stk.push_back(c);
}
}
if (ans % 2 == 0)
cout << "No";
else
cout << "Yes";
return 0;
}
Leetcode第84场双周赛
第一题:2363. 合并相似的物品
分析:map可以用来同时存储一个物品的价值和重量,利用哈希表的自动升序,key存价值,将两个数组中相同价值的重量加在一起,再遍历三次即可得到结果
代码:
class Solution {
public:
vector<vector<int>> mergeSimilarItems(vector<vector<int>>& items1, vector<vector<int>>& items2) {
vector<vector<int>> res;
map<int,int> m;
for(int i = 0; i < items1.size() ;i++)
{
m[items1[i][0]] = items1[i][1];
}
for(int j = 0; j < items2.size() ;j++)
{
m[items2[j][0]] += items2[j][1];
}
for(auto it = m.begin(); it != m.end(); it++)
{
res.push_back(vector<int>{it->first, it->second});
}
return res;
}
};
第二题:2364. 统计坏数对的数目
分析:可以先将题目的不等式转换成j - nums[j] != i - nums[i]。这样问题便转换成了一个从后面的数向前面的数找不同的个数。利用哈希表记录每个数出现的次数,由下标 i 可知前面存在 i 个数,用i减去相同的个数便得到最后不同的个数。
代码:
class Solution {
public:
long long countBadPairs(vector<int>& nums) {
int n = nums.size();
long long res = 0;
unordered_map<int,int>count;
for(int i = 0; i < n; i ++)
{
nums[i] = i - nums[i];
}
count[nums[0]] ++;
for(int i = 1; i < n; i ++)
{
res += (i - count[nums[i]]);
count[nums[i]] ++;
}
return res;
}
};
Leetcode第305场周赛
第一题:2367. 算术三元组的数目
分析:由于该题的数据范围也比较小,还是可以通过暴力枚举。
代码:
class Solution {
public:
int arithmeticTriplets(vector<int>& nums, int diff) {
int res = 0;
for(int i = 0;i < nums.size();i ++){
for(int j = i + 1;j < nums.size();j ++){
for(int k = j + 1;k < nums.size();k ++)
if(nums[j] - nums[i] == diff&&nums[k] - nums[j] == diff)
res ++;
}
}
return res;
}
};
分析:用一个vector数组来存储是否为限制节点,这样可以将o(n)复杂度降到o(1)。用二维vector数组restore来存储边,比如restore[0]存储的是与0相连的节点。unordered_set 来装存储已经遍历过的节点,由于0不可能是限制节点,0可以直接放进去。思路参考
代码:
class Solution {
public:
int r = 1;
vector<vector<int>> restore;
unordered_set<int> set;
vector<bool> Contain;
int reachableNodes(int n, vector<vector<int>>& edges, vector<int>& restricted) {
set.insert(0);
restore.resize(100005);
Contain.resize(1e5+5);
for(int i = 0;i < restricted.size();i++){
Contain[restricted[i]] = true;
}
for(int i = 0;i < edges.size();i++){
restore[edges[i][0]].push_back(edges[i][1]);
restore[edges[i][1]].push_back(edges[i][0]);
}
auto a = restore[0];
for(int i = 0;i < a.size();i++){
if(!Contain[a[i]])
dfs(a[i]);
}return r;
}
void dfs(int nextVal)
{
if(set.find(nextVal) != set.end())
return;
set.insert(nextVal);
r++;
auto a = restore[nextVal];
for(int i = 0;i < a.size();i++){
if(!Contain[a[i]])
dfs(a[i]);
}
}
};