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 写题。

最后,给大家推荐几道 STL 的题目:P3613 P5266-map P5250-set

posted @ 2025-07-27 10:12  雨梦-H  阅读(760)  评论(0)    收藏  举报