一、LeetCode单周赛 306
1、2373.矩阵中的局部最大值
(1)原题链接:力扣
https://leetcode.cn/problems/largest-local-values-in-a-matrix/
(2)解题思路:
由于数据范围比较小,因此我们可以直接暴力遍历一遍每个3x3矩阵的最大值,然后存到答案数组中即可。
(3)代码:
class Solution {
public:
vector<vector<int>> largestLocal(vector<vector<int>>& grid) {
int n = grid.size();
vector<vector<int>> res(n - 2, vector<int> (n - 2));
for(int i = 0; i < n - 2; i ++ ) {
for(int j = 0; j < n - 2; j ++ ) {
int t = 0;
for(int k = i; k < i + 3; k ++ ) {
for(int l = j; l < j + 3; l ++ ) {
t = max(t, grid[k][l]);
}
}
res[i][j] = t;
}
}
return res;
}
};
2、2374.边积分最高的节点
(1)原题链接:力扣
https://leetcode.cn/problems/node-with-highest-edge-score/
(2)解题思路:
用一个数组来保存每个节点的边积分,然后遍历一遍找到边积分最大的节点,注意数据范围这里需要用long long定义数组来防止超出数据范围。
(3)代码:
typedef long long LL;
class Solution {
public:
int edgeScore(vector<int>& edges) {
int n = edges.size();
vector<LL> w(n);
for(int i = 0; i < n; i ++ ) w[edges[i]] += i;
int res = 0;
for(int i = 0; i < n; i ++ ) {
if(w[i] > w[res]) res = i;
}
return res;
}
};
3、2375.根据模式串构造最小数字
(1)原题链接:力扣
https://leetcode.cn/problems/construct-smallest-number-from-di-string/
(2)解题思路:
利用next_permutation函数来求答案字符串,只需判断用该函数得到的下一个字符串是否满足题目要求即可,若不满足则得到另一个可能满足条件的字符串,继续重复判断,直到得到满足条件的字符串退出循环。
(3)代码:
class Solution {
public:
string smallestNumber(string pattern) {
string res;
for(int i = 1; i <= pattern.size() + 1; i ++ ) {
res += to_string(i);
}
while (true) {
bool flag = true;
for(int i = 0; i < pattern.size(); i ++ ) {
if(pattern[i] == 'I' && res[i] > res[i + 1]) {
flag = false;
break;
}else if(pattern[i] == 'D' && res[i] < res[i + 1]){
flag = false;
break;
}
}
if(flag) break;
//next_permutation是求当前排列的下一个排列(按字典序升序的下一个序列),如1234的next_permutation是1243。
next_permutation(res.begin(), res.end());
}
return res;
}
};
二、AcWing周赛 64
1、4506.三国语言
(1)原题链接:4506. 三国语言 - AcWing题库
(2)解题思路:
用一个字符串来保存某句话的后缀,若找到相应匹配的后缀,则输出相应的国家即可。
(3)代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
while (n -- ) {
string str;
cin >> str;
int n = str.size();
string cmp = "";
for(int i = n - 2; i < n; i ++) cmp += str[i];
if(cmp == "po") puts("FILIPINO");
cmp = "";
for(int i = n - 4; i < n; i ++) cmp += str[i];
if(cmp == "desu" || cmp == "masu") puts("JAPANESE");
cmp = "";
for(int i = n - 5; i < n; i ++) cmp += str[i];
if(cmp =="mnida") puts("KOREAN");
}
return 0;
}
2、4507.子数组异或和
(1)原题链接:4507. 子数组异或和 - AcWing题库
(2)解题思路:
用两个哈希表来存连续子数组的异或和,一个存下标为奇数的连续子数组的异或和,一个存下标为偶数的连续子数组的异或和。
对于每个连续子数组,假设这一连续子数组的下标是[i ~ j],异或前缀和为s,由第一个条件可知 ==> s[j] == s[i - 1],所以可以枚举每一个j,找到j左边异或前缀和与s[j]相等的数目。
(3)代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>
using namespace std;
typedef long long LL;
const int N = 3e5 + 10;
int a[N];
int main()
{
int n;
cin >> n;
for(int i = 1; i <= n; i ++ ) cin >> a[i];
LL res = 0, sum = 0;
unordered_map<int, int> s[2];
s[0][0] ++;
for(int i = 1; i <= n; i ++ ) {
sum ^= a[i];
/*res += s[i % 2][sum];
s[i % 2][sum] ++;*/
res += s[i & 1][sum];
s[i & 1][sum] ++;
}
cout << res << endl;
return 0;
}