Leetcode第230场周赛
A题:5689. 统计匹配检索规则的物品数量
- 纯模拟
class Solution {
public:
int countMatches(vector<vector<string>>& items, string ruleKey, string ruleValue){
int res = 0;
for(auto &x : items){
if(ruleKey == "type"){
res += ruleValue == x[0];
}else if(ruleKey == "color"){
res += ruleValue == x[1];
}else{
res += ruleValue == x[2];
}
}
return res;
}
};
B题:1774. 最接近目标价格的甜点成本
- DFS或者是4进制枚举,只需要把所有的情况枚举出来就好了,或者是完全背包也可以做
class Solution {
public:
int closestCost(vector<int>& baseCosts, vector<int>& toppingCosts, int target) {
int n = baseCosts.size(),m = toppingCosts.size();
int res = 1e9;
for(int i = 0;i < n;i ++){
for(int j = 0;j < 1 << m * 2;j ++){
int t = baseCosts[i];
for(int k = 0;k < m;k ++){
int wei = j >> k * 2 & 3;
if(wei == 3){
t = 1e9;
break;
}
t += wei * toppingCosts[k];
}
if(abs(t - target) < abs(res - target) || abs(t - target) == abs(res - target) && t < res){
res = t;
}
}
}
return res;
}
};
C题:1775. 通过最少操作次数使数组的和相等
- 能够组成的数字一定是在m 到 6 * n之间(n < m),然后枚举m 到 n * 6 之间的数字,如果是sum > 要枚举的数字,那么我们首先就先用6,然后是5...,否则相反,还有要上取整。
class Solution {
public:
int work(vector<int>v,int x){
int sum = 0;
for(int i = 1;i < 7;i ++){
sum += i * v[i];
}
int res = 0;
if(sum > x){
int cha = sum - x;
for(int i = 6;i > 1;i --){
int t = i - 1;
if(t * v[i] >= cha){
res += (cha + t - 1) / t;
break;
}else{
cha -= t * v[i];
res += v[i];
}
}
}else{
int cha = x - sum;
for(int i = 1;i < 7;i ++){
int t = 6 - i;
if(t * v[i] >= cha){
res += (cha + t - 1) / t;
break;
}else{
cha -= t * v[i];
res += v[i];
}
}
}
return res;
}
int minOperations(vector<int>& nums1, vector<int>& nums2) {
int n = nums1.size(),m = nums2.size();
if(n > m){
return minOperations(nums2,nums1);
}
vector<int>v1(7),v2(7);
int res = 1e9;
if(n * 6 < m) return -1;
for(auto &x :nums1){
v1[x] ++;
}
for(auto &x : nums2){
v2[x]++;
}
for(int i = m;i <= n * 6;i ++){
res = min(res,work(v1,i) + work(v2,i));
}
return res;
}
};
D题:车队 II
class Solution {
public:
//这道题必须想清楚一点,那就是如果ans[i]有正值,那么一定是cars[i]和某个cars[j](j>i且speed[j]<speed[i])发生碰撞
//相撞之后,所谓的融合,其实可以理解为cars[i]消失了,cars[j]状态不变
//所以我们只关注一辆车右边,不关注其左边,它的左边对它没有任何影响。可以考虑从右往左遍历
vector<double> getCollisionTimes(vector<vector<int>>& cars) {
vector<double>ans(cars.size());
//设立一个单调栈,栈底最慢,栈顶最快
stack<int>S;
for(int i=cars.size()-1;i>=0;i--){
while(S.size()){
//如果栈顶比我快,我追不上它,可以考虑等它消失之后我去撞它前面的,所以将它pop
if(cars[S.top()][1]>=cars[i][1])S.pop();
//如果栈顶比我慢,我就决定去碰它了
else{
//如果它不会消失,那我肯定能碰它,break
if(ans[S.top()]<0)break;
//如果它会消失,我需要计算一下在它消失之前能否追上它
double d=ans[S.top()]*(cars[i][1]-cars[S.top()][1]);
//能追上,那我肯定碰它,break
if(d>cars[S.top()][0]-cars[i][0])break;
//追不上,那算了,追它前面的车
else S.pop();
}
}
if(S.empty())ans[i]=-1;
else{
//相对距离除以相对速度
double t=double(cars[S.top()][0]-cars[i][0])/double(cars[i][1]-cars[S.top()][1]);
ans[i]=t;
}
S.push(i);
}
return ans;
}
};
作者:oldyan
链接:https://leetcode-cn.com/problems/car-fleet-ii/solution/cdan-diao-zhan-by-oldyan-ij4k/
知足常乐!