Acwing第77场周赛+Leetcode第319场周赛补题

Acwing第77场周赛 

第一题:4716. 进球 - AcWing题库

分析:用哈希表存储每个队伍的名字以及该名字出现的次数。由于最多只会有两个队伍,所以当该队伍名字出现次数超过n/2时就可以判定该队伍获胜了。

代码实现:

#include 
#include 
#include 
#include 

using namespace std;

int main()
{
    int n;
    cin >> n;

    unordered_map hash;
    for (int i = 0; i < n; i ++ )
    {
        string str;
        cin >> str;
        hash[str] ++ ;

        if (hash[str] * 2 > n)
        {
            cout << str << endl;
            break;
        }
    }

    return 0;
}

第二题: 4717. 环形队伍 - AcWing题库

分析:找到一种实现方法就好了,无论人数有多少,前七个都是ROYGBIV,后面再加人就不断往后加GBIV。

代码实现:

#include 
#include 
#include 

using namespace std;

char s[] = "ROYGBIV";

int main()
{
    int n;
    cin >> n;
    string res;
    for (int i = 1; i <= 7; i ++ )
        res += s[i - 1];

    // 不断加入GBIV
    for (int i = 8; i <= n; i ++ )
    {
        if (i % 4 == 0) res += s[3];
        if (i % 4 == 1) res += s[4];
        if (i % 4 == 2) res += s[5];
        if (i % 4 == 3) res += s[6];
    }

    cout << res << endl;

    return 0;
}

 


Leetcode第319场周赛

第一题:6233. 温度转换 - 力扣(LeetCode)

分析:要返回的类型是vector数组,所以定义一个vector数组将两个值输入之后return就好了

代码实现:

class Solution {
public:
    vector convertTemperature(double celsius) {
        vector a;
        a.push_back(celsius + 273.15);
        a.push_back(celsius * 1.80 + 32.00);
        return a;
    }
};

第二题:6234. 最小公倍数为 K 的子数组数目 - 力扣(LeetCode)

分析:此题和leetcode第316场周赛的第二题类似,只不过这题是要求最小公倍数,那题是要求最大公因数。两个数a和b的最大公倍数可以表示为\left ( a\ast b\right )\div gcd\left (a,b \right ),其中gcd(a,b)为a和b的最小公倍数。同样使用双指针遍历数组加cnt计数的方法。如果这个数就是题目给定的k本身,那么该子数组的最小公倍数就是他本身,cnt直接++。否则的话再遍历数组,用a维护右指针的前一个数,判断a与右指针所指元素的最小公倍数是否为k,是的话就cnt ++,然后每次循环更新一遍a。

代码实现:

class Solution {
public:
    int subarrayLCM(vector& nums, int k) {
        int cnt = 0;
        for(int i = 0;i < nums.size();i ++){
            if(nums[i] == k) cnt ++;
            int a = nums[i];
            for(int j = i + 1;j < nums.size();j ++){
                a = (nums[j] * a)/gcd(nums[j],a);
                if(a == k){
                    cnt ++;
                }
                else if(a > k) break;
            }
        }
        return cnt;
    }
};

第三题:6235. 逐层排序二叉树所需的最少操作数目 - 力扣(LeetCode)

分析:把每层所有数都取出来,问题变为给一个序列,序列两两元素可以任意交换,求最少的交换次数使得序列有序。最终答案就是每层答案的和。从1到n枚举下标i,只要当前序列下标i的元素ai不等于目标元素中下标i的元素bi就不断交换ai到目标位置,交换次数即所求结果。思路参考

代码实现:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    vector> vec;

    // 把同一层的数都集中到同一个序列里
    void dfs(TreeNode *node, int d) {
        if (node == nullptr) return;
        while (vec.size() <= d) vec.push_back(vector());
        vec[d].push_back(node->val);
        dfs(node->left, d + 1);
        dfs(node->right, d + 1);
    }

    int gao(vector &A) {
        // 求每个元素的目标位置
        vector B = A;
        sort(B.begin(), B.end());
        unordered_map mp;
        for (int i = 0; i < B.size(); i++) mp[B[i]] = i;

        int ret = 0;
        for (int i = 0; i < A.size(); i++) {
            // 不断将 A[i] 交换到目标位置,直到 A[i] = B[i]
            // 注意别写成 if 了
            while (A[i] != B[i]) {
                swap(A[i], A[mp[A[i]]]);
                ret++;
            }
        }
        return ret;
    }

public:
    int minimumOperations(TreeNode* root) {
        dfs(root, 0);
        int ans = 0;
        for (auto &A : vec) ans += gao(A);
        return ans;
    }
};

你可能感兴趣的:(周赛补题,leetcode,算法,职场和发展)