第一题:无人机打靶
结构体排序法
收获细节:
1. 关于哈希表一个用hash.first,和first.second来进行访问
2. 可以使用哈希表来映射简写和全称之间的关系
3. 用for auto遍历哈希表,再用first和second可以实现映射输出
4. 有个易错点,如果定义的是char,那么输入时要使用单引号’ ‘,string 输入时使用双印号“ ”
#include <bits/stdc++.h>
using namespace std;
int n; // 存储队伍的数量
unordered_map<string,string> color{ // 用来映射颜色编码简写和全程之间的关系
{"g", "green"},
{"r", "red"},
{"b", "blue"},
{"p", "purple"}
};
unordered_map<string,int> team; // 哈希表,记录各颜色对应的无人机数
struct G{
string name;
int garde;
}g[30];
bool cmp(G a,G b){
return (a.garde >= b.garde);
}
int main(){
cin >> n;
for(int i = 0; i < n ; i++){
cin >> g[i].name >> g[i].garde;
team[g[i].name]++; // 用来记录每个颜色的队伍数
}
sort(g , g+n , cmp);
for(auto c : team){
cout << color[c.first] << ' ' << c.second << endl;
}
cout << endl;
for(int i = 0 ; i < n; i++)
cout << g[i].name << ' ' << g[i].garde << endl;
return 0;
}
假设该题不要区分简写和全称,可以不使用哈希,使用string数组即可
string color[]= {"b","r","g","p"};
for(int i = 0 ; i < 4; i++)
cout << color[i] << ' ' << team[color[i]] << endl;
/*
-
-
-
*/
第二题:顺子
从扑克牌中抽取5张,其中A、J、Q、K分别表示 1、11、12、13,大小王用 0 表示,如果五张牌可以连成顺序则称为顺子,大小王可以表示任意数字。现在输入五张牌的牌面,判断是否为顺子。
方法一:差额做法
算法思想:把五张牌都存储在状态数组里面。通过搜索从1-K每一张牌的后四张,记录距离成为顺子的牌数差额为多少,如果差额可以被大小王覆盖,则是顺子,否则不是。
时间复杂度O(n);
#include <bits/stdc++.h>
using namespace std;
bool st[14]; // 记录牌数
int king;// 记录大小王数量
int c; // 记录差额数量,差几张可以成为顺子
bool isShunzi(){
int cnt = 0;
for(int i = 1; i <= 13; i++) //忽略大小王,记录每种牌的数量
if(st[i]) cnt++;
for(int i = 1; i <= 13; i++){
if(!st[i]) continue;
int c = 0; //重置差额
int n = 5,j = i;
while(n){
int j = (j+1)%14;
if(!st[j]) c++; //差额加1
n--;
}
if(c <= king) return true; //如果差额的数量小于大小王的数量,即可以用大小王补齐
}
return false;
}
方法二:
算法思想
最大值 - 最小值 < 5 并且 除了大小王没重复的牌 → 是顺子
bool isStraight(vector<int>& nums) {
// 初始化最大值和最小值,maxv初始为-1确保能够取到更小的值,
// minv初始为20确保能够取到更大的值
int maxv = -1, minv = 20;
unordered_set<int> s; // 使用无序集合存储已经出现的牌面值,用于判断是否重复
for (int x : nums)
{
if (x == 0) continue; // 跳过大小王
maxv = max(maxv, x); // 更新最大值
minv = min(minv, x); // 更新最小值
if (s.count(x)) return false; // 如果已经出现过该牌面值,说明不是顺子,返回false
s.insert(x); // 将当前牌面值加入集合
}
return (maxv - minv) < 5; // 最大值和最小值之差小于5说明可以组成顺子
}
主函数:
int main(){
for(int i = 0 ; i<5; i++){
char j;
cin >> j ;
if(j=='A') st[1] = true;
else if(j=='J') st[11] = true;
else if(j=='Q') st[12] = true;
else if(j=='K') st[13] = true;
else if(j=='G') king ++; // G代表大小王
else st[j-'0'] = true;
}
if(isShunzi()) cout << "Yes"<<endl;
else cout << "No" << endl;
return 0;
}