LeetCode 单周赛313 && LeetCode双周赛88 && AcWing周赛71

一、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)原题链接:力扣icon-default.png?t=M85Bhttps://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)原题链接:力扣icon-default.png?t=M85Bhttps://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)原题链接:力扣icon-default.png?t=M85Bhttps://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;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值