zoukankan      html  css  js  c++  java
  • 单周赛 254 题解

    本场周赛,略有难度,知识点:字符串,构造,贪心,广度优先搜索,二分答案

    作为子字符串出现在单词中的字符串数目

    给定字典 (w),给定字符串 (s),判断 (w) 中有多少字符串是 (s) 的子串

    题解

    直接模拟

    // go
    func numOfStrings(patterns []string, word string) int {
        ans := 0
        for _, v := range(patterns) {
            if strings.Contains(word, v) {
                ans++
            }
        }
        return ans
    }
    

    构造元素不等于两相邻元素平均值的数组

    给定一个数组 (A),保证元素互不相同,要求重排列,使得除去头尾的其他每一个元素都不是左右两个元素的平均值

    数据规定

    (1leq nleq 10^5)

    题解

    将数组排序,用两个指针从头尾开始扫,先放头再放尾,就可以保证每一个元素都小于/大于相邻的左右两个元素,时间复杂度 (O(nlog n))

    // cpp
    class Solution {
    public:
        vector<int> rearrangeArray(vector<int>& nums) {
            sort(nums.begin(), nums.end());
            int n = nums.size();
            vector<int> ans;
            int i = 0, j = n - 1;
            while (i <= j) {
                if (i <= j) ans.push_back(nums[i++]);
                if (i <= j) ans.push_back(nums[j--]);
            }
            return ans;
        }
    };
    
    // go
    func rearrangeArray(nums []int) []int {
        n := len(nums)
        sort.Ints(nums)
        ans := []int{}
        for i, j, k := 0, n - 1, 0; i <= j; k++ {
            if i <= j {
                ans, i = append(ans, nums[i]), i + 1
            }
            if i <= j {
                ans, j = append(ans, nums[j]), j - 1
            }
        }
        return ans
    }
    
    

    数组元素的最小非零乘积

    给定正整数 (p),给定数组 (A),包含 1, 2, .., 2^p - 1 中的所有正整数

    现在可以选择数组中的任意两个元素 (a, b),把其中一位不同的二进制位互相替换

    例如对于 1011, 0100,可以换成 1111, 0000

    可以执行任意多次操作,要求计算操作后数组乘积的最小值

    数据规定

    (1leq pleq 60)

    题解

    可以执行任意多次操作,就很有搞头了

    (m = 2^p - 1),选取 (a, m - a),一定可以保证他们的二进制互补,互补的含义是每一位都不相同

    例如 (m = 2^4 - 1 = 15),选取 (a = (0111)_2 = 7, b = (1000)_2 = 8)

    我们执行一定次数的操作,一定可以使得 (a, b) 最终成为 (1, m - 1),例如在上述例子中为 (1, 14),这样的乘积是最小的

    考虑互补的对数,一共有 (2^{p - 1} - 1) 对,每一对的乘积为 (2^p - 2),再乘上不配对的 (2^p - 1),因此最终的答案为

    [(2^p - 1)cdot (2^p - 2)^{2^{p - 1} - 1} ]

    利用快速幂,时间复杂度为 (O(p))

    // go
    const mod int = 1e9 + 7
    
    func minNonZeroProduct(p int) int {
        return (1<<p - 1) % mod * qpow(1<<p-2, 1<<(p-1)-1, mod) % mod
    }
    
    func qpow(a int, b int, mod int) int {
        ans := 1
        for a %= mod; b > 0; b >>= 1 {
            if b&1 != 0 {
                ans = ans * a % mod
            }
            a = a * a % mod
        }
        return ans
    }
    

    你能穿过矩阵的最后一天

    给定一个 (row imes col) 的二进制矩阵,每一天都会有一个位置水漫金山,有水的位置用 (1) 表示,其他地方用 (0)

    你可以从第一行的任意位置出发,从最后一行的任意一个位置离开,请计算出能够安全离开矩阵的最后一天

    题解

    二分答案,然后用 bfs 判断可行性

    判定 (k) 是否可行,只要设定一个全 (0) 矩阵,将前 (k) 天的水漫金山情况用 (1) 表示,然后将第一行所有不为 (0) 的位置放入队列进行 bfs 即可,设 (M = colcdot row),时间复杂度 (O(M log M))

    // cpp
    #define pii pair<int, int>
    const int DX[] = {1, 0, -1, 0};
    const int DY[] = {0, -1, 0, 1};
    bool bfs(int d, int m, int n, vector<vector<int>> &grid) {
        queue<pii> q;
        for (int i = 1; i <= n; ++i)
            if (!grid[1][i]) q.push(pii{1, i}), grid[1][i] = 1;
        
        while (!q.empty()) {
            auto [x, y] = q.front(); q.pop();
            if (x == m) return 1;
            for (int i = 0; i < 4; ++i) {
                int tx = DX[i] + x;
                int ty = DY[i] + y;
                if (tx >= 1 && tx <= m && ty >= 1 && ty <= n && !grid[tx][ty])
                    q.push(pii{tx, ty}), grid[tx][ty] = 1;
            }
        }
        return 0;
    }
    class Solution {
    public:
        int latestDayToCross(int row, int col, vector<vector<int>>& cells) {
            int m = cells.size(), n = cells[0].size();
            int l = 0, r = row * col, ans = 0;
            while (l <= r) {
                int mid = (l + r) >> 1;
                vector<vector<int>> grid(row + 7, vector<int>(col + 7, 0));
                for (int i = 0; i < mid; ++i) grid[cells[i][0]][cells[i][1]] = 1;
                if (bfs(mid, row, col, grid)) ans = mid, l = mid + 1;
                else r = mid - 1;
            }
            return ans;
        }
    };
    
  • 相关阅读:
    zz学习技术的三部曲:WHAT、HOW、WHY
    zz一种理想的在关系数据库中存储树型结构数据的方法
    某外企SQL Server面試題
    C语言中的指针 &与*
    剖析SQL Server执行计划(zz)
    UNICODE,GBK,UTF8区别
    (Part 1Chapter 14) High Performance Linux Clusters with OSCAR, Rocks, OpenMosix, and MPI
    关于GtkTreeView和 MVC的一篇好文章 入木三分
    一个混合 MPI_Init() 和 gtk_init() 的实例序
    (Part 2Chapter 57) High Performance Linux Clusters with OSCAR, Rocks, OpenMosix, and MPI
  • 原文地址:https://www.cnblogs.com/ChenyangXu/p/15147228.html
Copyright © 2011-2022 走看看