leetCode第391场周赛题解(c++)

文章讲述了如何用编程解决关于哈沙德数的判定、换水策略优化及数组中交替子数组的计数问题,涉及C++中lambda表达式的使用。
摘要由CSDN通过智能技术生成

3100263.哈沙德数

如果一个整数能够被其各个数位上的数字之和整除,则称之为 哈沙德数(Harshad number)。给你一个整数 x 。如果 x 是 哈沙德数 ,则返回 x 各个数位上的数字之和,否则,返回 -1 。

示例 1:

输入: x = 18

输出: 9

解释:

x 各个数位上的数字之和为 9 。18 能被 9 整除。因此 18 是哈沙德数,答案是 9 。

示例 2:

输入: x = 23

输出: -1

解释:

x 各个数位上的数字之和为 5 。23 不能被 5 整除。因此 23 不是哈沙德数,答案是 -1 。

提示:

  • 1 <= x <= 100
#include<iostream>
using namespace std;
int sumOfTheDigitsOfHarshadNumber(int x) {
    int sum=0;int t=x;
    while(t!=0){
        sum+=t%10;
       // cout<<sum<<" ";
        t=t/10;
        
    }
    if(x%sum==0) return sum;
    else return -1;
}
int main(){
    int q=sumOfTheDigitsOfHarshadNumber(18);
    cout<<"q= "<<q<<endl;
    return 0;
}

100235.换水问题II

给你两个整数 numBottles 和 numExchange 。

numBottles 代表你最初拥有的满水瓶数量。在一次操作中,你可以执行以下操作之一:

  • 喝掉任意数量的满水瓶,使它们变成空水瓶。
  • 用 numExchange 个空水瓶交换一个满水瓶。然后,将 numExchange 的值增加 1 。

注意,你不能使用相同的 numExchange 值交换多批空水瓶。例如,如果 numBottles == 3 并且 numExchange == 1 ,则不能用 3 个空水瓶交换成 3 个满水瓶。

返回你 最多 可以喝到多少瓶水。

(说白了这个题意思就是,我们有多少瓶水就可以有多少空瓶,但是每次用空瓶数来换一瓶水的数目必须+1)

#include<iostream>
using namespace std;
int maxBottlesDrunk(int numBottles, int numExchange) {
    int a=numBottles; //现在的空瓶子数
    int b=numExchange; //每次需要换一瓶水的空瓶子数
    int c=0; //换水次数
    if(a<b) return numBottles;
    else{
         while(a-b>=0){
        a=a-b+1;
        b++;
        c++;
    }
    return numBottles+c;
    }
   
}
int main(){
    int tar=maxBottlesDrunk(15,5);
    cout<<tar;
    return 0;
}

100266.交替子数组计数

给你一个

二进制数组

nums 。

如果一个

子数组

中 不存在 两个 相邻 元素的值 相同 的情况,我们称这样的子数组为 交替子数组 

返回数组 nums 中交替子数组的数量。

示例 1:

输入: nums = [0,1,1,1]

输出: 5

解释:

以下子数组是交替子数组:[0] 、[1] 、[1] 、[1] 以及 [0,1] 。

示例 2:

输入: nums = [1,0,1,0]

输出: 10

解释:

数组的每个子数组都是交替子数组。可以统计在内的子数组共有 10 个。

提示:

  • 1 <= nums.length <= 105
  • nums[i] 不是 0 就是 1 。
#include<iostream>
#include<vector>
#include<map>
using namespace std;
long long countAlternatingSubarrays(vector<int>& nums) {
    //遍历肯定可以
    long long ans=0;
    int n=nums.size();
    for(int i=0; i<n-1; i++){
         for(int j=i; j<n-1; j++){
         if(nums[j]!=nums[j+1]) {
            ans++;

         }
         else break;

        }
      
    }
    return ans+n;

}
int main(){
    vector<int> nums={0,1,1,1};
    long long  tar=  countAlternatingSubarrays(nums);
    cout<<tar;
    return 0;

}

但是超时了。。。

今天去考csp了,寄。。。连三百也没有。

重新看灵茶的回放,应该这么写:

#include<iostream>
#include<vector>
#include<map>
using namespace std;
long long countAlternatingSubarrays(vector<int>& nums) {
    
   long long ans=0,cnt=0;
   for(int i=0;i<nums.size();i++){
    if(i>0&&nums[i]==nums[i-1]) cnt=1;
    else cnt++;
    ans+=cnt;
   }
   return ans;

}
int main(){
    vector<int> nums={0,1,1,1};
    long long  tar=  countAlternatingSubarrays(nums);
    cout<<tar;
    return 0;

}

3102.最小化曼哈顿距离

给你一个下标从 0 开始的数组 points ,它表示二维平面上一些点的整数坐标,其中 points[i] = [xi, yi] 。

两点之间的距离定义为它们的

曼哈顿距离

请你恰好移除一个点,返回移除后任意两点之间的 最大 距离可能的 最小 值。

示例 1:

输入:points = [[3,10],[5,15],[10,2],[4,4]]
输出:12
解释:移除每个点后的最大距离如下所示:
- 移除第 0 个点后,最大距离在点 (5, 15) 和 (10, 2) 之间,为 |5 - 10| + |15 - 2| = 18 。
- 移除第 1 个点后,最大距离在点 (3, 10) 和 (10, 2) 之间,为 |3 - 10| + |10 - 2| = 15 。
- 移除第 2 个点后,最大距离在点 (5, 15) 和 (4, 4) 之间,为 |5 - 4| + |15 - 4| = 12 。
- 移除第 3 个点后,最大距离在点 (5, 15) 和 (10, 2) 之间的,为 |5 - 10| + |15 - 2| = 18 。
在恰好移除一个点后,任意两点之间的最大距离可能的最小值是 12 。

示例 2:

输入:points = [[1,1],[1,1],[1,1]]
输出:0
解释:移除任一点后,任意两点之间的最大距离都是 0 。

提示:

  • 3 <= points.length <= 105
  • points[i].length == 2
  • 1 <= points[i][0], points[i][1] <= 108
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;
int minimumDistance(vector<vector<int>>& points) {
    int n=points.size();
    int ans=1e9;
    //ban表示被移除的点编号
    auto calc=[&](int ban){
        //将每个点的x-y以及x+y从小到大排序
        vector<pair<int,int>>A,B;
        for(int i=0;i<n;i++) if(i!=ban){
        //p 是一个引用,指向 points 数组中第 i 行的 vector<int>。这样做可以让我们方便地访问第 i 行中的各个元素。
            auto &p=points[i];
            A.push_back(make_pair(p[0]-p[1],i));
            B.push_back(make_pair(p[0]+p[1],i));
        }
        sort(A.begin(),A.end());
        sort(B.begin(),B.end());
        //答案就是max(max(x-y),max(x+y))
        int d=max(A.back().first-A[0].first,B.back().first-B[0].first);
        ans=min(ans,d);
        //返回和最大曼哈顿距离有关的四个点编号
        return vector<int>{A.back().second,A[0].second,B.back().second,B[0].second};

    };
    //枚举和最大曼哈顿距离有关的四个点,看移除哪个
    for(int ban:calc(-1)) calc(ban);
    return ans;

}
int main(){
    vector<vector<int> >points{{3,10},{5,15},{10,2},{4,4}};
    cout<<minimumDistance(points)<<endl;
    return 0;

}

  • `auto calc = [&](int ban){...}` 这行代码定义了一个使用 lambda 表达式的内联函数 `calc`。lambda 表达式是一种方便在需要时定义匿名函数的方法,你可以在代码中直接声明这些函数,而不必为它们单独命名。
  • 在这个代码中,`calc` 是一个接受一个 `int` 类型参数 `ban` 的函数。当你调用 `calc` 时,它会执行 lambda 表达式中的代码块,根据传入的 `ban` 参数进行计算,然后返回一个与最大曼哈顿距离有关的四个点的编号。
  • Lambda 表达式可以访问其定义范围内的变量,这使得它们非常灵活和方便。在这里,lambda 表达式使用了外部变量 `points`,`n`,`ans` 等来对一些操作进行计算。
  • 在 C++ 中,lambda 表达式可以通过 `[captures](params) { body }` 的语法来定义,其中 `captures` 表示lambda表达式捕获列表,`params` 表示参数列表,`body` 表示函数体。 

(感觉好难。。。)

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
引用\[1\]:这段代码是一个解决LeetCode上某个题目的C++实现,具体是一个双指针的解法。该题目是计算一个数组中的积水量。代码中使用了两个指针分别指向数组的左右边界,然后通过比较左右指针所指向的元素的大小,来确定当前位置的积水量。具体的计算方法是,如果左指针所指向的元素小于右指针所指向的元素,则对左指针的左边进行操作,如果左指针所指向的元素大于等于右指针所指向的元素,则对右指针的右边进行操作。在每一次操作中,都会更新左边的最大值和右边的最大值,并计算当前位置的积水量。最后返回总的积水量。\[1\] 引用\[2\]:这段代码是另一个解决LeetCode上某个题目的C++实现,具体是一个深度优先搜索的解法。该题目是计算一个二维网格中从起点到终点的可行路径数量。代码中使用了递归的方式进行深度优先搜索,从起点开始,每次向下或向右移动一步,直到到达终点。在每一步移动中,会判断当前位置是否有障碍物,如果有障碍物则返回0,如果到达终点则返回1,否则继续递归搜索下一步的位置。最后返回总的可行路径数量。\[2\] 引用\[3\]:这段代码是另一个解决LeetCode上某个题目的C++实现,具体是一个动态规划的解法。该题目是计算一个数组中的积水量。代码中使用了动态规划的思想,通过遍历数组中的每个元素,分别计算该元素左边和右边的最大值,并计算当前位置的积水量。最后返回总的积水量。\[3\] 综上所述,这三段代码分别是解决LeetCode上不同题目的C++实现,分别使用了双指针、深度优先搜索和动态规划的方法来解决问题。 #### 引用[.reference_title] - *1* *3* [Leetcode 热题100 42.接雨水(C++ 多种解法,错过可惜)](https://blog.csdn.net/qq_51933234/article/details/124637883)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [[C++]Leetcode 不同路径 || 解题思路及详解](https://blog.csdn.net/weixin_62712365/article/details/123951736)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值