一、LeetCode单周赛 313
1、6192. 公因数的数目
(1)原题链接:力扣https://leetcode.cn/problems/number-of-common-factors/
(2)解题思路:
由于数据范围比较小,所以直接,从 1 枚举到 a ,判断同时为 a 和 b 的因数的个数即可。
(3)参考代码:
class Solution {
public:
int commonFactors(int a, int b) {
int res = 0;
for(int i = 1; i <= a; i ++) {
if(a % i == 0 && b % i == 0) res ++;
}
return res;
}
};
2、6193. 沙漏的最大总和
(1)原题链接:力扣https://leetcode.cn/problems/maximum-sum-of-an-hourglass/
(2)解题思路:
1、先按顺序保存每个九宫格的如图两个红框中的数的和。
2、再按顺序求出每个九宫格的数值总和。
3、再减去之前保存的红框中的数的和,即为每个沙漏的总和。
4、找到最大值即为答案。
(3)参考代码:
class Solution {
public:
int maxSum(vector<vector<int>>& grid) {
int dx[8] = {-1, -1, -1, 0, 1, 1, 1, 0};
int dy[8] = {-1, 0, 1, 1, 1, 0, -1, -1};
int res = 0;
int n = grid.size() - 1;
int m = grid[0].size() - 1;
vector<int> dis;
for(int i = 1; i < n; i ++) {
for(int j = 0; j < m - 1; j ++ ) {
dis.push_back(grid[i][j] + grid[i][j + 2]);
}
}
int maxm = 0;
int l = 0;
for(int i = 1; i < n; i ++) {
for(int j = 1; j < m; j ++ ) {
int tmp = grid[i][j];
for(int k = 0; k < 8; k ++) {
int x = i+dx[k];
int y = j+dy[k];
tmp += grid[x][y];
}
tmp -= dis[l ++];
maxm = max(maxm, tmp);
}
}
res = maxm;
return res;
}
};
3、6194. 最小XOR
(1)原题链接:力扣https://leetcode.cn/contest/weekly-contest-313/problems/minimize-xor/
(2)解题思路:
1、先统计num2中 1 的个数cnt;
2、从num1的高位开始遍历,若当前二进制位为 1 ,则 x 的当前为也为 1, 因为异或相同为0;此外,要保证 x 中 1的个数小于 cnt 。
3、若步骤 2 做完 1 的个数仍小于cnt, 则从 x 的低位开始遍历,遇 0 置 1 直至满足 cnt 。
(3)参考代码:
class Solution {
public:
int minimizeXor(int num1, int num2) {
int res = 0;
int cnt = 0;
int a = num2;
while(a)
{
if(a & 1) cnt ++;
a >>= 1;
}
for(int i = 30; i >= 0; i --) {
if(((num1 >> i) & 1) && cnt) {
cnt --;
res += 1 << i;
}
}
for(int i = 0; i <= 30; i ++) {
if(cnt == 0) break;
if(((res >> i) & 1) == 0) {
cnt --;
res += 1 << i;
}
}
return res;
}
};
二、 LeetCode双周赛88
1、2423.删除字符使频率相同
(1)原题链接:力扣https://leetcode.cn/problems/remove-letter-to-equalize-frequency/
(2)解题思路:
枚举需要删除的字母,并检查剩下字母出现的频率是否相同。
(3)参考代码:
class Solution {
public:
bool equalFrequency(string word) {
int cnt[26] = {0};
for(char c: word) cnt[c - 'a'] ++;
for(int i = 0; i < 26; i ++ )
if(cnt[i] > 0) {
cnt[i] --;
int t = 0;
for(int j = 0; j < 26; j ++ )
if(cnt[j] > 0) {
if(t == 0) t = cnt[j];
else if(t != cnt[j]) goto FAILED;
}
return true;
//回复字母i
FAILED:
cnt[i] ++;
}
return false;
}
};
2、2424.最长上传前缀
(1)原题链接:力扣https://leetcode.cn/problems/longest-uploaded-prefix/
(2)解题思路:
1、用set维护1~n;
2、更新元素也就是删掉当前的video;
3、由于最长上传前缀,是不会随中间某个值的删除而改变的,所以当前的最长上传前缀一定就是st.begin() - 1;
(3)参考代码:
class LUPrefix {
set<int> st;
public:
LUPrefix(int n) {
for(int i = 1; i <= n + 1; i ++ ) {
st.insert(i);
}
}
void upload(int video) {
st.erase(video);
}
int longest() {
return *st.begin() - 1;
}
};
/**
* Your LUPrefix object will be instantiated and called as such:
* LUPrefix* obj = new LUPrefix(n);
* obj->upload(video);
* int param_2 = obj->longest();
*/
3、2425.所有数对的异或和
(1)原题链接:力扣https://leetcode.cn/problems/bitwise-xor-of-all-pairings/
(2)解题思路:
1、了解异或运算的性质:
2、由自反性可知,若一个数被异或偶数次则该数等于不用异或;
3、由题可知,nums1中的元素进行异或运算的次数是nums2.size()次,同理,nums2中的元素会被异或nums1.size()次。
(3)参考代码:
class Solution {
public:
int xorAllNums(vector<int>& nums1, vector<int>& nums2) {
int res = 0;
int n = nums1.size(), m = nums2.size();
if((n & 1) == 0 && (m & 1) == 0) return 0;
else if((n & 1) == 0) {
for(auto& num: nums1) res ^= num;
return res;
}
else if((m & 1) == 0) {
for(auto& num: nums2) res ^= num;
return res;
}
else {
for(auto& num1: nums1) {
for(auto& num2: nums2) {
res = res ^ num1 ^ num2;
}
}
return res;
}
return res;
}
};
三、AcWing周赛71
1、4621.三个整数
(1)原题链接:4621. 三个整数 - AcWing题库
(2)解题思路:
由于题目的数据范围比较小,直接看题写代码即可。
(3)参考代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
int a, b, c, d;
cin >> a >> b >> c >> d;
int x, y, z;
for(int i = a; i <= b; i ++) {
for(int j = b; j <= c; j ++ ) {
for(int k = c; k <= d; k ++) {
if(x + y <= z) break;
if(i + j > k) {
cout << i << ' ' << j << ' ' << k << ' ';
return 0;
}
}
}
}
return 0;
}
2、4622.整数拆分
(1)原题链接:4622. 整数拆分 - AcWing题库
(2)解题思路:
1、首先明确一点,在一定的范围内,由哥德巴赫猜想可知任何一个大于2的整数可以表示成三个质数之和。因此,本题的最大值就是3。
2、当输入的这个数是质数时,答案就是1。
3、当输入的数不是质数且是偶数时,答案就是2。因为,即任一大于2的偶数都可写成两个质数之和。
4、当输入的数不是质数且是奇数时,需要分类讨论,若(n - 2)为质数则输出2,反之则输出3。
(3)参考代码:
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL;
bool is_prime(LL x)
{
if(x < 2) return false;
for(LL i = 2; i <= x / i; i ++ ) {
if(x % i == 0) return false;
}
return true;
}
int main()
{
LL n;
cin >> n;
if(is_prime(n)) puts("1");
else {
if(n % 2 == 0) puts("2");
else
{
//为什么减2?
//因为一个奇数要拆分为两个质数和的话,一个数是奇数,一个数是偶数,而偶数中只有2是质数
if(is_prime(n - 2)) puts("2");
else puts("3");
}
}
return 0;
}