P11227 [CSP-J 2024] 扑克牌 题解
前言
本篇题解会给大家介绍三种解法,第一种是数组,后两种为 STL 解法。
题目大意
现有 $n$ 张扑克牌,求至少还要添加几张牌才能获得一副完整的扑克牌(去掉大小王)。
形式化题意:给出 $n$ 个字符串,设 $x$ 为去重后的字符串个数,则答案为 $52 - x$。
1.数组解法
思路
因为需要去重,所以我们可以考虑开一个 bool 类型数组,只要出现过这张牌就赋值为 $1$。
那么问题又来了,因为数组下标只能为整数,不能直接以字符串作为下标。观察数据,发现一张扑克牌只有两个元素:花色和点数,所以我们可以开一个二维数组,第一维代表花色,第二维代表点数,然后用 $1$ ~ $4$ 分别表示四个花色,点数同理。
代码参考
#include<bits/stdc++.h>
using namespace std;
int n;
bool a[5][20];
int main(){
cin>>n;
while(n--){
char x,y; //x,b为花色,y,c为点数
int b,c;
cin>>x>>y;
if(x=='D') b=1;
if(x=='C') b=2;
if(x=='H') b=3;
if(x=='S') b=4;
if(y=='A') c=1;
if(y>='2'&&y<='9') c=y-'0';
if(y=='T') c=10;
if(y=='J') c=11;
if(y=='Q') c=12;
if(y=='K') c=13;
a[b][c]=1;
}
int ans=0;
for(int i=1;i<=4;++i){
for(int j=1;j<=13;++j){
ans+=a[i][j];
}
}
cout<<52-ans;
return 0;
}
2.map解法
思路
因为下标为字符串,所以我们可以考虑用 STL 中的 map 来求解,map 可看作是一个下标可以为任意元素的数组。想了解更多的同学可以在这里学习。
下面给大家介绍一些常用的操作:
| 操作 | 作用 |
|---|---|
| map<a,b> | 设置一个下标为 a 类型,元素为 b 类型的 map 容器 |
| m[a]=b | 在 m 中加入一个元素 |
| m.erase(a) | 删除元素 a / 删除迭代器为 a 的元素 |
| m.clear( ) | 清空 m |
| m.empty( ) | 判断 m 是否为空 |
| m.size( ) | 返回 m 中元素的个数 |
对于每张扑克,直接将它加入 map 容器中即可。
代码参考
#include<bits/stdc++.h>
using namespace std;
int n;
map<string,bool> m; //定义一个下标类型为string,元素类型为bool的map
int main(){
cin>>n;
while(n--){
string s;
cin>>s;
m[s]=1; //加入m中
}
cout<<52-m.size();
return 0;
}
3.set解法
思路
如果只考虑去重的话,我们可以使用 STL 中的 set,它是一个很好用的去重工具。具体操作:每次插入一个新元素时,如果容器中没有相同的元素才会插入容器,反之,则不插入。想了解更多的同学可以在这里学习。
下面给大家介绍一些常用操作:
| 操作 | 作用 |
|---|---|
| set | 设置一个元素为 a 类型的 set 容器 |
| s.insert(a) | 在 s 中插入一个元素 a |
| s.erase(a) | 删除元素 a / 删除迭代器为 a 的元素 |
| s.clear( ) | 清空 s |
| s.empty( ) | 判断 s 是否为空 |
| s.size( ) | 返回 s 中元素的个数 |
对于每张扑克,直接将它加入 set 容器中即可。
代码参考
#include<bits/stdc++.h>
using namespace std;
int n;
set<string> ans; //定义一个元素类型为string的set
int main(){
cin>>n;
while(n--){
string s;
cin>>s;
ans.insert(s); //加入ans中
}
cout<<52-ans.size();
return 0;
}
总结
使用 STL 中的容器可以更好地帮助我们完成程序,可以大大减少码量,所以建议大家多用 STL 写题。

浙公网安备 33010602011771号