1589. 所有排列中的最大和 #差分 #贪心

题目链接

题意

给定整数数组nums,以及查询数组requests,其中requests[i] = [starti, endi] 。第i个查询求 nums[starti] + nums[starti + 1] + ... + nums[endi - 1] + nums[endi] 的结果 。

你可以任意排列 nums 中的数字,请你返回所有查询结果之和的最大值,请将答案对 109 + 7 取余 后返回。

分析

我们先离线获得需要查询的区间,并统计该查询涉及端点的出现次数(也就是频数)。显然由贪心思想,我们要想答案尽可能地大,就应该将值更大的元素安排到出现次数更多的端点上,即高频数\(\times\)大元素。

typedef long long ll;
const int MAXN = 1e5 + 5;
const int MOD = 1e9 + 7;
class Solution {
private:
int cf[MAXN];
vector<int> used;
public:
int maxSumRangeQuery(vector<int>& nums, vector<vector<int>>& requests) {
for (int i = 0; i < requests.size(); i++){
int a = requests[i][0], b = requests[i][1];
cf[a]++;
cf[b + 1]--;
}
int sum = 0;
for (int i = 0; i < nums.size(); i++){
sum += cf[i];
used.push_back(sum);
}
sort(used.begin(), used.end(), greater<int>());
sort(nums.begin(), nums.end(), greater<int>());
ll ans = 0;
for (int i = 0; i < used.size(); i++){
ans += ((ll)used[i] * (ll)nums[i]);
}
return ans % MOD;
}
};

1590. 使数组和能被 P 整除 #前缀和 #哈希表

题目链接

题意

给定正整数数组 nums,请你移除 最短 子数组(即原数组中连续的一组元素,可以为 空),使得剩余元素的 被 p 整除。 不允许 将整个数组都移除。要你返回需要移除的最短子数组的长度,如果无法满足题目要求,返回 -1 。

分析

令\(lastmod = \sum{nums}\ \%\ p\),当\(lastmod==0\)显然无需操作,答案为0;当\(lastmod\not= 0\),我们的问题接下来就变为从原数组中找到一个最短子数组,使得\(\sum{(该子数组)}\% p = lastmod\),此时原数组剩余部分都能被\(p\)整除!

要求一段连续子数组之和,需要前缀和维护。不过注意这个和是经过模\(p\)运算处理的,这样是为了找到一段子数组模\(p\)加法运算得到上一段所说的\(lastmod\)。我们每遍历一个元素,就将其对应的模\(p\)前缀和\(curmod\)在哈希表中映射其对应位置,用于未来查询相应的\(targetMod\)的位置。如下图所示。

如何对当前\(i\)下已知的\(curmod\)求出对应的\(targetMod\)呢?当\(curmod \geq lastmod\)时,之前按下图所示,\(targetMod = curmod - lastmod\);当\(curmod\leq lastmod\)时,就需要加上一个\(p\),即\(targetMod = curmod - lastmod + p\)。上面两种情况合起来就是,\(targetMod = curmod - lastmod + p\)。我们求出\(targetMod\)的值,再通过哈希表查询\(targetMod\)的位置\(pos\),此时长度为\(pos-i\)、区间\([pos, i]\)的子数组,满足其和模\(p\)是等于\(lastmod\)的,更新长度,直到所有元素遍历完,便得到最短长度了。

此处初始化有个重要的小细节,之所以要pos[0] = -1;,是因为在第一次targetMod==0curmod==lastmod时,你从哈希表查询到的位置刚好也是lastmod(刚刚更新的位置),更新的长度就变成0了!!显然它应该更新长度是从[0, lastmod位置]

typedef long long ll;
class Solution {
private:
unordered_map<ll, int> pos; //用于记录总和取了模之后的最新位置,即离当前元素最近的位置,保证题目的“最短”
public:
int minSubarray(vector<int>& nums, int p) {
ll sum = 0;
for(int i = 0; i < nums.size(); i++) sum += (ll)nums[i];
ll lastmod = sum % (ll)p, curmod = 0;
if(lastmod == 0) return 0; //直接返回
if(sum < p) return -1; //和 比 模数更小,显然无法满足题目要求
pos[0] = -1;//一定要先初始化-1!!!
int minlen = 0x3f3f3f3f;
for(int i = 0; i < nums.size(); i++){
curmod = (curmod + nums[i]) % p;
pos[curmod] = i;
ll targetMod = (curmod - lastmod + p) % p;
if(pos.count(targetMod))
minlen = min(minlen, i - pos[targetMod]);
}
return (minlen < nums.size()) ? minlen : -1;
}
};

1591. 奇怪的打印机 II #拓扑排序

题目链接

题意

一个打印机有如下两个特殊的打印规则:

  • 每一次操作时,打印机会用同一种颜色打印一个矩形的形状,每次打印会覆盖矩形对应格子里原本的颜色。
  • 一旦矩形根据上面的规则使用了一种颜色,那么 相同的颜色不能再被使用 。

给定 m x n 的矩形 targetGrid ,其中 targetGrid[row][col] 是位置 (row, col) 的颜色。如果能按上述规则打印出矩形targetGrid,返回 true ,否则返回 false

题目分析

注意到数据范围均在\(60\)以内,意味着我们可以枚举所有的颜色。

class Solution {
private:
int bottom[65], top[65], left[65], right[65];
int InD[65] = { 0 };
vector<int> H[65]; //边集
bool vis[65][65] = { false };
int n, m;
queue<int> myque;
public:
bool isPrintable(vector<vector<int>>& targetGrid) {
n = targetGrid.size(), m = targetGrid[0].size();
for (int i = 1; i <= 60; i++) { //初始化
top[i] = left[i] = 0x3f3f3f3f;
bottom[i] = right[i] = -1;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
int curcolor = targetGrid[i][j];
bottom[curcolor] = max(bottom[curcolor], i); //最大下边界
right[curcolor] = max(right[curcolor], j); //以下同理
top[curcolor] = min(top[curcolor], i);
left[curcolor] = min(left[curcolor], j);
}
} //确定所有颜色的上下左右边界
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
int curcolor = targetGrid[i][j];
for (int faColor = 1; faColor <= 60; faColor++) {
if (faColor == curcolor || vis[faColor][curcolor]) continue; //重边或者重点,跳过。
if (top[faColor] <= i && i <= bottom[faColor]
&& left[faColor] <= j && j <= right[faColor]) { //fa颜色集合包含了curcolor集合
H[faColor].push_back(curcolor); //说明两颜色存在偏序关系
vis[faColor][curcolor] = true;
InD[curcolor]++;
}
} }
}
/*以下为拓扑排序,通过拓扑排序判断这些偏序关系即有向图,是否存在环,有环说明两颜色集合互相包含*/
int cnt = 0;
for (int i = 1; i <= 60; i++)
if (InD[i] == 0) {
myque.push(i);
cnt++;
}
while (!myque.empty()) {
int u = myque.front();
myque.pop();
for (int i = 0; i < H[u].size(); i++) {
int v = H[u][i];
InD[v]--;
if (InD[v] == 0) {
myque.push(v);
cnt++;
}
}
}
return (cnt == 60);
}
};

LeetCode双周赛#35的更多相关文章

  1. leetcode 双周赛9 进击的骑士

    一个坐标可以从 -infinity 延伸到 +infinity 的 无限大的 棋盘上,你的 骑士 驻扎在坐标为 [0, 0] 的方格里. 骑士的走法和中国象棋中的马相似,走 “日” 字:即先向左(或右 ...

  2. leetcode 双周赛9 找出所有行中最小公共元素

    给你一个矩阵 mat,其中每一行的元素都已经按 递增 顺序排好了.请你帮忙找出在所有这些行中 最小的公共元素. 如果矩阵中没有这样的公共元素,就请返回 -1. 示例: 输入:mat = [[,,,,] ...

  3. [每日一题2020.06.16] leetcode双周赛T3 5423 找两个和为目标值且不重叠的子数组 DP, 前缀和

    题目链接 给你一个整数数组 arr 和一个整数值 target . 请你在 arr 中找 两个互不重叠的子数组 且它们的和都等于 target .可能会有多种方案,请你返回满足要求的两个子数组长度和的 ...

  4. LeetCode双周赛#36

    1604. 警告一小时内使用相同员工卡大于等于三次的人 题目链接 题意 给定两个字符串数组keyName和keyTime,分别表示名字为keytime[i]的人,在某一天内使用员工卡的时间(格式为24 ...

  5. LeetCode双周赛#34

    5492. 分割字符串的方案数 #组合公式 #乘法原理 #区间分割 题目链接 题意 给定01二进制串\(s\),可将\(s\)分割为三个非空 字符串\(s_1,s_2,s_3\),即(\(s_1+s_ ...

  6. LeetCode双周赛#33 题解

    5480. 可以到达所有点的最少点数目 #贪心 题目链接 题意 给定有向无环图,编号从0到n-1,一个边集数组edges(表示从某个顶点到另一顶点的有向边),现要找到最小的顶点集合,使得从这些点出发, ...

  7. Leetcode 双周赛#32 题解

    1540 K次操作转变字符串 #计数 题目链接 题意 给定两字符串\(s\)和\(t\),要求你在\(k\)次操作以内将字符串\(s\)转变为\(t\),其中第\(i\)次操作时,可选择如下操作: 选 ...

  8. LeetCode第8场双周赛(Java)

    这次我只做对一题. 原因是题目返回值类型有误,写的是 String[] ,实际上应该返回 List<String> . 好吧,只能自认倒霉.就当涨涨经验. 5068. 前后拼接 解题思路 ...

  9. LeetCode 第 15 场双周赛

    1287.有序数组中出现次数超过25%的元素 1288.删除被覆盖区间 1286.字母组合迭代器 1289.下降路径最小和 II 下降和不能只保留原数组中最小的两个,hacked. 1287.有序数组 ...

随机推荐

  1. B. Kay and Snowflake 解析(思維、DFS、DP、重心)

    Codeforce 685 B. Kay and Snowflake 解析(思維.DFS.DP.重心) 今天我們來看看CF685B 題目連結 題目 給你一棵樹,要求你求出每棵子樹的重心. 前言 完全不 ...

  2. 【转】Setting up SDL 2 on Visual Studio 2019 Community

    FROM: http://lazyfoo.net/tutorials/SDL/01_hello_SDL/windows/msvc2019/index.php Setting up SDL 2 on V ...

  3. SharedPreferences源码分析

    分析达成目标 了解基本实现 SharePreferences是否线程安全 SharePreferences的mode参数是什么 了解apply与commit的区别 导致ANR的原因 Android8. ...

  4. NB-IoT的RLC子层服务功能

    NB-IoT只支持RLC子层的确认模式(Acknowledgement Mode,AM),不支持非确认模式(Unacknowledged Mode,UM). 对于支持UP模式的UE,NB-IoT支持R ...

  5. UbuntuStudio20.04安装教程(双系统安装,windows10已安装)

    硬件和系统: acer4750(原i3换i7,加固态硬盘200多G,原机械硬盘500G由光驱改装,内存由2G增加为6G)2010年购买3300,性价比高,硬件升级后2020年不过时 windows10 ...

  6. MySQL安装及安装问题解答(二)

    在安装过程中难免会有一些异常情况出现,笔者对一部分异常情况做出解答以供参考 1.MySQL未能成功启动 在输入net start mysql后提示 MySQL 服务正在启动, MySQL 服务无法启动 ...

  7. JSP启动,错误500,实例化Servlet类异常

    jps的页面报 HTTP   500  -Internal Server Error 实例化Servlet类[servlet.Userservler]异常 javax.servlet.ServletE ...

  8. java联系人管理系统简单设计

    本文实例为大家分享了java联系人管理系统毕业设计,供大家参考,具体内容如下 要求:  请使用XML保存数据,完成一个联系人管理系统.      用户必须经过认证登录后方可以使用系统.      注册 ...

  9. HTML生成横向的PDF

    HTML生成PDF请参照:https://www.cnblogs.com/yunfeiyang-88/p/10984740.html 如要生成横向的PDF:在html模板的style标签里面加入@pa ...

  10. 数字取证autopsy——性能优化(二)

    介绍: 在开始使用autopsy之前,我们先对autopsy进行性能优化.如果还没有安装autopsy,请点击连接https://github.com/sleuthkit/autopsy/releas ...