目录
C++扑克牌(poker)
一、题目要求
1、编程实现
2、输入输出
二、算法分析
三、程序编写
四、运行结果
五、考点分析
六、推荐资料
C++扑克牌(poker)
2024年CSP-J认证第二轮第一题
一、题目要求
1、编程实现
小 P 从同学小 Q 那儿借来一副 n 张牌的扑克牌。本题中我们不考虑大小王,此时每张牌具有两个属性:花色和点数。花色共有4种:方片、草花、红桃和黑桃。点数共有13 种,从小到大分别为A23456789TJ Q K。注意:点数 10 在本题中记为 T。
我们称一副扑克牌是完整的,当且仅当对于每一种花色和每一种点数,都恰好有一张牌具有对应的花色和点数。由此,一副完整的扑克牌恰好有4x13=52 张牌。以下图片展示了一副完整的扑克牌里所有的 52 张牌。
小 P借来的牌可能不是完整的,为此小P准备再向同学小S借若干张牌。可以认为小S每种牌都有无限张,因此小P可以任意选择借来的牌。小 P想知道他至少得向小S借多少张牌,才能让从小 S和小 Q借来的牌中,可以选出 52 张牌构成一副完整的扑克牌。
为了方便你的输入,我们使用字符D代表方片,字符C代表草花,字符H代表红桃,字符S代表黑桃,这样每张牌可以通过一个长度为2的字符串表示,其中第一个字符表示这张牌的花色,第二个字符表示这张牌的点数,例如 CA 表示草花 A,ST 表示黑桃 T(黑桃 10)。
2、输入输出
输入描述:
输出描述:
输入样例:
4
DQ
H3
DQ
DT
输出样例:
49
数据范围:
二、算法分析
- 从给定题目的初步分析本题难度不大,可以使用哈希数组进行模拟实现
- 思路就是建立一个哈希数组对应52张牌,将输入的每张扑克牌转换成对应的数组值,输入一张扑克牌就进行标记(赋值1),最后只要将52减去哈希数组中1的个数之后就是我们需要借的扑克牌数量
- 所以该题关键就是如何将输入的四种花色的扑克牌转换成对应的1-52这52个数字,这个其实也不难,我这边是将红桃设为前13张,黑桃设为14-26张,草花设为27-39张,方片设为40-52张
- 具体可以使用字符串或者字符数组来存放每次输入的扑克牌,然后判断第一个字符对应的花色,接着判断第二个字符对应点数,这里判断点数的时候需要转换一下将:A-1,T-10,J-11,Q-12,K-13;只要用两个switch case就可以解决
- 这样设计的算法由于是对n张牌处理,所以时间复杂度为O(n),空间复杂度是O(1)
三、程序编写
#include <bits/stdc++.h>
using namespace std;
const int N = 52;
int porker[N+1];
int main()
{
int n;
cin >> n;
for(int i=0;i<n;i++)
{
string s;
cin >> s;
switch(s[0])
{
case 'H'://红桃
{
int t = 0;
switch(s[1])
{
case 'A': t = 1;break;
case 'T': t = 10;break;
case 'J': t = 11;break;
case 'Q': t = 12;break;
case 'K': t = 13;break;
default: t = int(s[1]);break;
}
porker[t] = 1;break;
}
case 'S'://黑桃
{
int t = 13;
switch(s[1])
{
case 'A': t += 1;break;
case 'T': t += 10;break;
case 'J': t += 11;break;
case 'Q': t += 12;break;
case 'K': t += 13;break;
default: t += int(s[1]);break;
}
porker[t] = 1;break;
}
case 'C'://草花
{
int t = 26;
switch(s[1])
{
case 'A': t += 1;break;
case 'T': t += 10;break;
case 'J': t += 11;break;
case 'Q': t += 12;break;
case 'K': t += 13;break;
default: t += int(s[1]);break;
}
porker[t] = 1;break;
}
case 'D'://方片
{
int t = 13;
switch(s[1])
{
case 'A': t += 1;break;
case 'T': t += 10;break;
case 'J': t += 11;break;
case 'Q': t += 12;break;
case 'K': t += 13;break;
default: t += int(s[1]);break;
}
porker[t] = 1;break;
}
}
}
int s = 0;//牌数
for(int i=0;i<52;i++)
{
s += porker[i];
}
s = 52 - s;
cout << s << endl;
return 0;
}
PS:以上程序没有写文件操作,小朋友在真正作答的时候加上文件读取和关闭即可
本文作者:小兔子编程 作者首页:小兔子编程-CSDN博客
四、运行结果
4
DQ
H3
DQ
DT
49
五、考点分析
难度级别:一般,这题相对而言在于花色和数组的转换,具体主要考查如下:
- 分析题目,找到解题思路
- 充分掌握变量和数组的定义和使用
- 学会模拟算法的使用
- 学会switch语句的使用
- 学会输入流对象cin的使用,从键盘读入相应的数据
- 学会for循环的使用,在确定循环次数的时候推荐使用学会
- 掌握输出流对象cout的使用,与流插入运算符 << 结合使用将对象输出到终端显示
- 学会分析题目,算法分析,将复杂问题模块化,简单化,从中找到相应的解题思路
- 充分掌握变量定义和使用、分支语句、循环语句和模拟算法的应用
PS:方式方法有多种,小朋友们只要能够达到题目要求即可!
六、推荐资料
- 所有考级比赛学习相关资料合集【推荐收藏】