“三带一”算法题
文章目录
- 斗地主中的“三带一”牌型判断
- 题目描述
- 三带一牌型定义
- 输入格式
- 输出格式
- 样例输入
- 样例输出
- 说明
- 评测数据范围
- 思路分析
- 问题核心
- 思路拆解
- 代码实现
- 复杂度分析
- 总结的知识点
好的,我会将你提供的题目描述、输入输出格式、思路分析、代码段及其逐行讲解、复杂度分析以及总结的知识点整合成一个完整的博客内容。以下是详细的博客文章:
斗地主中的“三带一”牌型判断
题目描述
小蓝和小桥玩斗地主,小蓝只剩四张牌了,他想知道是否是“三带一”牌型。
三带一牌型定义
所谓“三带一”牌型,即四张手牌中,有三张牌一样,另外一张不与其他牌相同。换种说法,四张手牌经过重新排列后,可以组成 AAAB
型。
输入格式
- 第一行:输入一个整数 ( T ),代表斗地主的轮数。
- 接下来 ( T ) 行:每行输入一个长度为 4 的字符串,代表小蓝的手牌。
字符 { 'A','2','3','4','5','6','7','8','9','X','J','Q','K' }
对应代表牌面 { A,2,3,4,5,6,7,8,9,10,J,Q,K }
。
牌面中不包含大小王。
输出格式
输出 ( T ) 行,每行一个字符串,如果当前牌是“三带一”牌型,输出 Yes
,否则输出 No
。
样例输入
5
AAAA
33X3
JQKX
6566
KKKQ
样例输出
No
Yes
No
Yes
Yes
说明
“四炸”牌型不属于“三带一”牌型。
评测数据范围
- 数据范围:( 1 \leq T \leq 50 )。
- 字符中只包含:{
A
,2
,3
,4
,5
,6
,7
,8
,9
,X
,J
,Q
,K
}。
思路分析
问题核心
判断给定的四张牌是否满足“三带一”的条件,即有三张相同的牌和一张不同的牌,并且排除“四炸”(四张相同的牌)的情况。
思路拆解
-
统计每种牌的数量:
- 使用哈希表(
HashMap
)来统计每种牌出现的次数。
- 使用哈希表(
-
检查是否满足“三带一”的条件:
- 检查是否有某一种牌出现三次,同时另一种牌出现一次。
- 确保总共只有两种不同的牌。
-
排除“四炸”情况:
- 如果所有牌都是相同的,则不是“三带一”。
代码实现
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
for (int i = 0; i < n; i++) {
Map<String, Integer> map = new HashMap<>();
String hand = sc.next();
// 统计每种牌的数量
for (char card : hand.toCharArray()) {
String cardStr = String.valueOf(card);
map.put(cardStr, map.getOrDefault(cardStr, 0) + 1);
}
boolean isThreeOfAKind = false;
boolean isOneOfAKind = false;
// 检查是否满足三带一的条件
for (int count : map.values()) {
if (count == 3) {
isThreeOfAKind = true;
} else if (count == 1) {
isOneOfAKind = true;
}
}
// 输出结果
if (isThreeOfAKind && isOneOfAKind && map.size() == 2) {
System.out.println("Yes");
} else {
System.out.println("No");
}
}
sc.close();
}
}
复杂度分析
- 时间复杂度:对于每一轮手牌,需要遍历长度为 4 的字符串并进行哈希表操作,因此时间复杂度为 ( O(T \cdot 4) ),即 ( O(T) ),其中 ( T ) 是轮数。
- 空间复杂度:使用了一个大小为最多 2 的哈希表来存储牌的数量,因此空间复杂度为 ( O(1) )。
总结的知识点
- 哈希表操作:如何使用
HashMap
统计每种牌的数量。 - 字符串处理:如何将字符串转换为字符数组进行遍历。
- 布尔标志位:如何通过布尔标志位来标记特定条件是否满足。
- 输入输出处理:使用
Scanner
进行输入输出操作。