IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【LeetCode第294场周赛】 -> 正文阅读

[数据结构与算法]【LeetCode第294场周赛】

A.

统计个数后,乘上 100 100 100 n n n下取整即可

class Solution {
public:
    int percentageLetter(string s, char letter) {
        int n = s.size();
        int c = 0;
        for(auto u : s)
            if(u == letter) c += 1;
        int res = c * 100 / n;
        return res;
    }
};

B.

先计算每个背包的剩余可装数量,按剩余数量从小到大排序,依次尽量填充即可。

class Solution {
public:
    int maximumBags(vector<int>& cap, vector<int>& rock, int rest) {
        int n = cap.size();
        for(int i = 0; i < n; ++i)
            cap[i] -= rock[i];
        sort(cap.begin(), cap.end());
        
        int res = 0;
        for(int i = 0; i < n; ++i) {
            int mn = min(rest, cap[i]);
            if(mn == cap[i]) res += 1;
            rest -= mn;
        }
        return res;
    }
};

C.

比较每个相邻线段的斜率是否相同即可

class Solution {
public:
    
    int gcd(int a, int b) {
        return b == 0 ? a : gcd(b, a % b);
    }
    
    int minimumLines(vector<vector<int>>& s) {
        sort(s.begin(), s.end(), [](const vector<int>& A, const vector<int>& B) {
            return A[0] < B[0]; 
        });
        
        int res = 0;
        int n = s.size();
        int prex = 0, prey = 0, pref = 1;
        for(int i = 1; i < n; ++i) {
            int ych = s[i][1] - s[i - 1][1];
            int xch = s[i][0] - s[i - 1][0];
            int fch = 1;
            if(ych < 0) fch = -1, ych = -ych;
            int g = gcd(xch, ych);
            xch /= g, ych /= g;
            if(prex == 0) {
                res += 1;
            } else {
                if(pref != fch || prex != xch || prey != ych) {
                    res += 1;
                } 
            }
            prex = xch;
            prey = ych;
            pref = fch;
        }
        return res;
    }
};

D.

枚举每个值 a i a_i ai?作为最小值的区间,我们称 a i a_i ai?作为最小值的区间为区间 i i i
为了防止重复计算,
a i a_i ai?的最远左端点为 i i i左边第一个 j j j,存在 a j < a i a_j<a_i aj?<ai?
a i a_i ai?的最远右端点为 i i i右边第一个 k k k,存在 a k ≤ a i a_k\leq a_i ak?ai?

区间 i i i的左边有 i ? j i-j i?j种选择,即选择 a i ? 1 a_{i-1} ai?1?、选择 a i ? 1 , a i ? 2 a_{i-1},a_{i-2} ai?1?,ai?2?、…、选择 a i ? 1 , . . . , a j ? 1 a_{i-1},...,a_{j-1} ai?1?,...,aj?1?
区间 j j j的右边有 k ? i k-i k?i种选择,即选择 a i + 1 a_{i+1} ai+1?、选择 a i + 1 , a i + 2 a_{i+1},a_{i+2} ai+1?,ai+2?、…、选择 a i + 1 , . . . , a k ? 1 a_{i+1},...,a_{k-1} ai+1?,...,ak?1?

那么计算所有区间 i i i的和,就可以转换为求区间 i i i的左边选择, 以及区间 i i i的右边选择。
我们可以维护前缀和 p r e pre pre,后缀和 s u f suf suf,双重前缀和 p p r e ppre ppre,以及双重后缀和 s s u f ssuf ssuf

双重前缀和

ppre[1] = 1 * a[1]
ppre[2] = 1 * a[1] + 2 * a[2]
ppre[3] = 1 * a[1] + 2 * a[2] + 3 * a[3]
...
ppre[n] = 1 * a[1] + 2 * a[2] + ... + n * a[n]

双重后缀和

ssuf[n] = 1 * a[n]
ssuf[n - 1] = 1 * a[n] + 2 * a[n - 1]
ssuf[n - 2] = 1 * a[n] + 2 * a[n - 1] + 3 * a[n - 2]
...
ssuf[n] = 1 * a[n] + 2 * a[n - 1] + ... + n * a[1]

计算 a j + 1 a_{j+1} aj+1? a k ? 1 a_{k-1} ak?1?这个区间的和,可以分为三部分:

  • a j + 1 a_{j+1} aj+1? a i ? 1 a_{i-1} ai?1?的双重前缀和 L v = p p r e i ? 1 ? p p r e j ? j × ( p r e i ? 1 ? p r e j ) Lv = ppre_{i-1}-ppre_{j}-j\times (pre_{i-1}-pre_{j}) Lv=pprei?1??pprej??j×(prei?1??prej?)
  • a k ? 1 a_{k-1} ak?1? a i + 1 a_{i+1} ai+1?的双重后缀和 R v = s s u f i + 1 ? s s u f k ? ( n ? k + 1 ) × ( s u f i + 1 ? s u f k ) Rv = ssuf_{i+1}-ssuf_{k}-(n-k+1)\times (suf_{i+1}-suf_{k}) Rv=ssufi+1??ssufk??(n?k+1)×(sufi+1??sufk?)
  • a i a_i ai?作为区间最小值的总和 M v = a i × ( k ? j ? 1 ) Mv = a_i\times (k-j-1) Mv=ai?×(k?j?1)

其中 L v Lv Lv出现了 k ? i k-i k?i次, R v Rv Rv出现了 i ? j i-j i?j次。
L v Lv Lv对区间的总和贡献为 L v × ( k ? i ) Lv\times (k-i) Lv×(k?i)
R v Rv Rv对区间的总和贡献为 R v × ( i ? j ) Rv\times (i-j) Rv×(i?j)
M v Mv Mv对区间的总和贡献为 M v Mv Mv

答案即为 ∑ i = 1 n a i × ( L v + R v + M v ) \sum_{i=1}^n a_i\times (Lv+Rv+Mv) i=1n?ai?×(Lv+Rv+Mv)

typedef long long ll;
class Solution {
public:
    
    const int mod = 1e9 + 7;
    
    int totalStrength(vector<int>& a) {
        ll res = 0;
        int n = a.size();
        vector<int> Lrank(n + 2, 0), Rrank(n + 2, 0);
        for(int i = 1; i <= n; ++i) Lrank[i] = i, Rrank[n - i + 1] = i;
        vector<ll> ppre(n + 2, 0), ssuf(n + 2, 0);
        vector<ll> pre(n + 2, 0), suf(n + 2, 0);
        for(int i = 1; i <= n; ++i) pre[i] = (pre[i - 1] + a[i - 1]) % mod;
        for(int i = n; i >= 1; --i) suf[i] = (suf[i + 1] + a[i - 1]) % mod;
        for(int i = 1; i <= n; ++i) ppre[i] = (ppre[i - 1] + 1ll * a[i - 1] * Lrank[i] % mod) % mod;
        for(int i = n; i >= 1; --i) ssuf[i] = (ssuf[i + 1] + 1ll * a[i - 1] * Rrank[i] % mod) % mod;
        
        vector<int> Rfirst(n + 2, 0);
        vector<int> Lfirst(n + 2, 0);
        stack<int> stk;
        for(int i = 1; i <= n; ++i) {
            while(!stk.empty() && a[stk.top() - 1] >= a[i - 1]) stk.pop();
            if(!stk.empty()) Lfirst[i] = stk.top();
            else Lfirst[i] = 0;
            stk.push(i);
        }
        
        while(!stk.empty()) stk.pop();
        for(int i = n; i >= 1; --i) {
            while(!stk.empty() && a[stk.top() - 1] > a[i - 1]) stk.pop();
            if(!stk.empty()) Rfirst[i] = stk.top();
            else Rfirst[i] = n + 1;
            stk.push(i);
        }
        
        for(int i = 1; i <= n; ++i) {
        	// 计算左边 
            ll Lf = Lfirst[i];
            ll Lv = ((ppre[i - 1] - ppre[Lf]) % mod + mod) % mod;
            Lv = (Lv - 1ll * Lrank[Lf] * (pre[i - 1] - pre[Lf]) % mod + mod) % mod;
            
            // 计算右边 
            ll Rf = Rfirst[i];
            ll Rv = ((ssuf[i + 1] - ssuf[Rf]) % mod + mod) % mod;
            Rv = (Rv - 1ll * Rrank[Rf] * (suf[i + 1] - suf[Rf]) % mod + mod) % mod;
            
            // 计算最小值 
            ll Mv = 1ll * (i - Lf) * (Rf - i) % mod * a[i - 1] % mod;
            
            // 计算左边和 乘 右边方案数,    计算右边和 乘 左边方案数 
            ll temp = (Lv * (Rf - i) % mod + Rv * (i - Lf) % mod) % mod;
            
            // 计算所有区间i的和 
            ll sum = (temp + Mv) % mod;
            
            res = (res + 1ll * sum * a[i - 1] % mod) % mod;
        }
        
        return res;
    }
};
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-05-24 18:28:41  更:2022-05-24 18:29:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 1:37:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码