感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接
🐒🐒🐒 个人主页
🥸🥸🥸 C语言
🐿️🐿️🐿️ C语言例题
🐣🐣🐣 python
🐓🐓🐓 数据结构C语言
🐔🐔🐔 C++
🐿️🐿️🐿️ 文章链接目录
🏀🏀🏀 笔试练习题
乒乓球框
题目解析
这道题的意思就是B是A的子集,因为要求的是B的种类A也要有,且A的数量还要大于等于B,并且我们可以从题目中知道每个乒乓是用大写字母来表示的,所以我们可以确定最多有26种不同的乒乓
此外这个题目的输入和输出结果有一点问题,
表示的是换行符,实际上的输入和输出是这样的
我们还需要注意题目中说的是多组数据,但是没具体给一个变量来表示有多少组,所以要用while循环去做
这道题很明显是用哈希表去做,哈希表常用于统计信息再去查找的情况
代码
#include <iostream>
using namespace std;
int main() {
string s1,s2;
while(cin>>s1>>s2)
{
int hash[26]={0};
int i=0;
for(auto ch:s1)hash[ch-'A']++;
for(auto ch:s2)hash[ch-'A']--;
for(i=0;i<26;i++)
{
if(hash[i]<0)
{
cout<<"No"<<endl;
break;
}
}
if(i==26)
cout<<"Yes"<<endl;
i=0;
}
return 0;
}
代码解析
while(cin>>s1>>s2)是判断是否还需要输入,和C语言的while(scanf(“%s”,&ch)!=EOF)一样
之后用范围for去遍历s1和s2
因为总共26个字母,所以我们用 i 去记for循环了多少次,如果i=26说明B是A的子集,如果i<26就说明还没有循环完就退出了,说明B比A多一些不一样的字母,或者相同字母的数量更多一些
组队竞赛
题目解析
这道题的意思就是每队有3个人,而我们只看中间那个人的水平值,也就是说无论队伍中最高水平的值有多高,最低水平值有多低,都只看中间那个人的水平值,所以我们要让中间那个人的水平值尽可能大,因为不止一队,且最后我们要求的是所以队伍的中间水平值之和,因此要合理安排队伍水平
我们以题目中的例子为例
因为这个顺序是乱的,我们以从小到大的顺序进行排序
因为最大值8和最小值1是不可能作为中间值的,所以我们可以直接把1和8去掉
此时就变成这样
此时最大值是5,假设最右边的最大值不是5,而是6
如果我们不去选择那个6而是选择5,那么就会编程下面这样
此时还剩的数字为2 5 6,因为最大值6和最小值2是不可能被作为水平值取到的,所以我们只能选择中间的5
这样的话我们会发现这个6我们就浪费掉了,因为如果不取的话后面就取不到了,因此我们每次取水平值的时候都要取最右边的第二个数字
而怎么快速的取呢,我们可以以从大到小的顺序取找
题目中告诉的n为2,也就是2组,总共有6个人,我们将他们的水平值用数组存起来,通过下标取找
因为是从最右边的第二个开始取,每次取后他们其实都是隔了一个数字的,因为那个数字是作为最大值被删掉的
所以我们直接用一个count取记录,每次去完后往左移动2,就行了
此外我刚刚还想到了用递归的方式,但是感觉不是很好,所以就不写了
代码
#include <iostream>
#include<algorithm>
using namespace std;
const long long N = 1e9 + 10;
long long arr[N] = {};
bool cmp(int a, int b) {
return a < b;
}
int main() {
int n = 0;
cin >> n;
for (int i = 0; i < 3 * n; i++)cin >> arr[i];
sort(arr, arr + 3 * n, cmp);
long long count = 0;
for (int i = 1; i <= n; i++)count += arr[3 * n - 2 * i];
cout << count << endl;
return 0;
}
删除相邻数字的最大分数(需要重做)
题目解析
这道题要注意理解题目,题目中有句话是这样说的
注意是所有等于ai-1和ai+1的元素都删除,我一开始以为是ai左边和右边的元素ai-1和ai+1删除,实际上我理解错了,是值为ai-1和ai+1,另外我后面还把ai-1和ai+1看成了元素的下标,以为是将为ai左边和右边值相等的元素都删除
我们可以用一个hash数组取记录相等的值有多少个
这样就变成了在hash表中选择不相邻的数字,使他们总和最大
这道题的解法是动态规划
我们可以用f[ i ]表示选到i位置后,i位置元素必选,此时的最大分数
g[ i ]表示选到i位置位置后,i位置元素不选,此时的最大分数
这样我们就可以列出状态转移方程
当i位置必选的时候,就可以向hash表中取i位置的值,而i-1就必定不可选(题目说明了ai-1要删除),也就是i-1不选时的最大分数,我们是用的g[ i-1]表示的
所以f[ i ]=hash[ i ]+g[ i-1]
因为f[ i ]表示的是i位置必选,但是最后的结果不一定是最大的,所以我们还需要取验证g[ i ]的值是否大于f[ i ]
在验证g[ i ]时我们需要讨论情况,我们可以不取i-1位置的值,也可以取i-1位置的值,因为题目没有明确说必须要从最大的值开始取,此时我们需要比较f[ i-1 ]和g[ i-1 ]谁最大
初始化g[ 0 ]=0,最后返回f[ n ]和g[ n ]的最大值
代码
const int N = 1e4 + 10;
int sum[N];
int f[N], g[N];
class Solution {
public:
int boredom(vector<int>& a) {
for (vector<int> ::iterator it = a.begin(); it < a.end(); it++) sum[*it]++;
for (int i = 1; i < N; i++) {
f[i] = i*sum[i] + g[i - 1];
g[i] = max(g[i - 1], f[i - 1]);
}
return max(g[N - 1], f[N - 1]);
}
};
代码解析
注意很多人有疑惑为什么是f[i] = isum[i] + g[i - 1],而不是f[i] = i + g[i - 1]
因为我们知道f[ i ]表示的是选择i位置的值这种情况,既然我们选择了i位置的值后,哈希表sum[ i ]的值就应该减减,值到为0,此时i位置的值就取完了,为了方便计算,我们就直接用的 isum[i],就省去了sum[i]减减这一步了