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