AcWing第56场周赛+力扣第298周赛

AcWing

第一题:分组

思路:题目的意思可以理解为统计重复数字的最大个数,用哈希表来计数即可。

代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>

using namespace std;

int n;

int main()
{
    cin >> n;
    unordered_map<int, int> mp;
    for(int i = 0; i < n; i ++)
    {
        int x;
        cin >> x;
        mp[x] ++;
    }
    int cnt = 0;
    for(auto [x, y] : mp)
    {
        cnt = max(cnt, y);
    }
    cout << cnt;
    return 0;
}

 第二题:格斗场

思路:用map来存储输入的数,对map中的数每两个进行一个比较,如果两个的差值小于m,就将小的数的个数变成0,统计map中的每个数的个数即可

代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>

using namespace std;

typedef pair<int, int> PII;
int n, m;

int main()
{
    cin >> n >> m;
    map<int, int> mp;
    for(int i = 0; i < n; i ++)
    {
        int x;
        cin >> x;
        mp[x] ++;
    }
    
    vector<PII> ans;
    for(auto [x, y] : mp)
    {
        ans.push_back({x, y});
    }
    
    for(int i = 0; i < ans.size(); i ++)
    {
        if(i + 1 < ans.size() && ans[i].first + m >= ans[i + 1].first)
            ans[i].second = 0;
    }
    int cnt = 0;
    for(auto [x, y] : ans)  cnt += y;
    cout << cnt <<endl;
    return 0;
}

第三题涉及到数学证明,有点复杂了就不补了。。。。



力扣

第一题:兼具大小写的最好英文字母

思路:用两个数组分别统计大写字母和小写字母出现的情况,如果一个字母的大小写都出现了(可能有多个,为了去最好的就从z向a遍历),就输出其大写字母

代码:

class Solution {
public:
    string greatestLetter(string s) {
        int a[26], b[26];
        memset(a, 0, sizeof a);
        memset(b, 0, sizeof b);
        for(int i = 0; i < s.size(); i ++)
        {
            if(s[i] >= 'A' && s[i] <= 'Z')  b[s[i] - 'A'] ++;
            else    a[s[i] - 'a'] ++;
        }
        string ans;
        for(int i = 0; i < 26; i ++)
        {
            if(a[i] && b[i])    ans = i + 'A';
        }
        return ans;
    }
};

 第二题:个位数字为K的整数和

思路:如果存在满足题目的整数集合必定有k * x % 10 == num % 10   x = 1,2,3,...,10 

而且k * x <= num,因为最小的个位数字为k的数就是k,如果在满足第一个的情况下k * x > num

表示不存在满足题目要求的一个集合,满足题目要求的集合应该为x-1个k和一个num-(x-1)*k,因为k*x % 10 == num % 10,所以num-(x-1)*k的个位数字一定为K 。注意要有一个特判,当num==0时,答案应该为0

代码

class Solution {
public:
    int minimumNumbers(int num, int k) {
        if(!num)    return 0;
        
        for(int i = 1; i <= 10; i ++)
        {
            if(i * k % 10 == num % 10 && i * k <= num)  return i;
        }
        return -1;
    }
};

 第三题:小于等于k的最长二进制子序列

思路:这题听了y总讲解后,豁然开朗,y总yyds!!!!  先将k转化为二进制字符串t,如果t的长度大于k,那么s的长度就是答案。否则分类讨论,这题主要是要去前导0,n = s.size(), m = t.size(),当取后面m-1个时,肯定是小于k的,为了取得最大的长度,其余的前导0即可;取后m个时又要分类讨论,当后m个字符串小于等于t时,直接去前导0即可;当后m个字符大于t时,就要从后m+1开始找,直到找到0为止,取0加上后m-1个字符,在去找前导0,其实这个是和去后m-1字符找前导0是一样的。

代码

class Solution {
public:
    int longestSubsequence(string s, int k) {
        string t;
        while(k)    t += to_string(k % 2), k /= 2;
        reverse(t.begin(), t.end());
        int n = s.size(), m = t.size();
        if(n < m)   return n;
        int res = m - 1;
        for(int i = 0; i < n - (m - 1); i ++)   if(s[i] == '0') res ++;
        string str = s.substr(n - m);
        if(str <= t)
        {
            int cnt = m;
            for(int i = 0; i < n - m; i ++)  if(s[i] == '0') cnt ++;
            res = max(res, cnt);
        }
        
        return res;
    }
};

 总结:好久没有写算法了,已经手生了,很多以前很快写出来的题现在有些半天,要开始进行康复训练了。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值