返回目录
题目描述
有这么一款单人卡牌游戏,牌面由颜色和数字组成,颜色为红、黄、蓝、绿中的一种,数字为0-9中的一个。游戏开始时玩家从手牌中选取一张卡牌打出,接下来如果玩家手中有和他上一次打出的手牌颜色或者数字相同的手牌,他可以继续将该手牌打出,直至手牌打光或者没有符合条件可以继续打出的手牌。
现给定一副手牌,请找到最优的出牌策略,使打出的手牌最多。
输入描述
输入为两行
- 第一行是每张手牌的数字,数字由空格分隔,
- 第二行为对应的每张手牌的颜色,用r y b g这4个字母分别代表4种颜色,字母也由空格分隔。
手牌数量不超过10。
输出描述
输出一个数字,即最多能打出的手牌的数量。
示例:
输入 | 1 4 3 4 5 r y b b r |
---|---|
输出 | 3 |
说明 | 如果打(1, r)-> (5, r),那么能打两张。 如果打(4,y) -> (4, b) -> (3, b),那么能打三张。 |
题目解析
本题连续出牌的条件是:
如果玩家手中有和他上一次打出的手牌颜色或者数字相同的手牌,他可以继续将该手牌打出
因此,我们可以基于回溯算法,来求解不同的出牌方式,而下张牌是否可出的条件是:
- 和上一张牌的数字相同,或者和上一张牌的颜色相同
Python算法源码
# 输入获取
nums = input().split() # 获取数字输入并以空格分割为列表
colors = input().split() # 获取颜色输入并以空格分割为列表
def dfs(cards, used, last, count, ans):
"""
回溯求解所有出牌情况的深度优先搜索函数
Args:
cards (list): 卡牌列表
used (list): 记录哪些牌已经使用过的列表
last (Card): 上一张出的牌
count (int): 当前出牌的数量
ans (list): 存储结果的列表
Returns:
None
"""
ans[0] = max(ans[0], count)
for i in range(len(cards)):
if used[i]:
continue
cur = cards[i]
if last and last.num != cur.num and last.color != cur.color:
continue
used[i] = True
dfs(cards, used, cur, count + 1, ans)
used[i] = False
class Card:
def __init__(self, num, color):
"""
初始化卡牌对象的构造函数
Args:
num (int): 卡牌数字
color (str): 卡牌颜色
Returns:
None
"""
self.num = num
self.color = color
# 算法入口
def getResult():
"""
获取结果的函数
Returns:
int: 最大出牌数量
"""
n = len(nums)
cards = [Card(int(nums[i]), colors[i]) for i in range(n)] # 将字符串转换为整数
ans = [0]
used = [False] * n
dfs(cards, used, None, 0, ans)
return ans[0]
# 算法调用
print(getResult()) # 输出结果
C算法源码
#include <stdio.h>
#define MAX(x,y) ((x) > (y) ? (x) : (y))
#define MAX_SIZE 10
// 定义卡牌结构体
typedef struct {
int number; // 数字
char color; // 颜色
} Card;
// 记录最大出牌数
int max_cards = 0;
// 记录输入的卡牌信息
Card deck[MAX_SIZE];
int deck_size = 0;
// 深度优先搜索函数
void depth_first_search(int used[], Card* previous, int count);
int main() {
// 读取卡牌数字
while (scanf("%d", &deck[deck_size].number)) {
deck_size++;
if (getchar() != ' ') break;
}
// 读取卡牌颜色
for (int i = 0; i < deck_size; i++) {
deck[i].color = (char) getchar();
getchar();
}
// 记录已使用的卡牌
int used[MAX_SIZE] = {0};
depth_first_search(used, NULL, 0);
// 输出结果
printf("%d\n", max_cards);
return 0;
}
// 深度优先搜索函数
void depth_first_search(int used[], Card* previous, int count) {
max_cards = MAX(max_cards, count);
for(int i = 0; i < deck_size; i++) {
// 如果当前牌已经使用过,则跳过
if(used[i]) continue;
// 当前牌
Card current_card = deck[i];
// 如果当前牌的数字与上一张牌的数字不同,并且颜色也不同,则跳过
if(previous != NULL && previous->number != current_card.number && previous->color != current_card.color) continue;
used[i] = 1;
depth_first_search(used, ¤t_card, count + 1);
used[i] = 0;
}
}
Java算法源码
import java.util.Scanner;
public class Main {
static class Card {
int num; // 数字
char color; // 颜色
Card(int num, char color) {
this.num = num;
this.color = color;
}
}
static int ans = 0; // 答案
static Card[] cards; // 卡牌数组
static int cardsSize; // 卡牌数量
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
cards = new Card[10]; // 假设最大容量为10
cardsSize = 0;
// 读取输入的数字和颜色
while (scanner.hasNextInt()) {
cards[cardsSize] = new Card(scanner.nextInt(), scanner.next().charAt(0));
cardsSize++;
if (!scanner.hasNext()) break;
}
int[] used = new int[10]; // 假设最大容量为10
dfs(used, null, 0);
System.out.println(ans);
}
// 深度优先搜索函数,用于寻找能够出的最大牌数
static void dfs(int[] used, Card last, int count) {
ans = Math.max(ans, count);
for (int i = 0; i < cardsSize; i++) {
if (used[i] == 1) continue;
Card cur = cards[i];
if (last != null && last.num != cur.num && last.color != cur.color) continue;
used[i] = 1;
dfs(used, cur, count + 1);
used[i] = 0;
}
}
}
4 条评论
[...]2024 C卷 100分序号题目知 识 点难易程度1密码输入检测数据结构/栈☆☆☆2分配土地几何问题☆☆☆3找座位逻辑分析☆☆☆4智能成绩表动态条件分析☆☆☆5内存冷热标记多条件排序☆☆☆6螺旋数字矩阵逻辑分析☆☆☆7围棋的气逻辑分析☆☆☆8分割平衡字符串逻辑分析☆☆☆9机器人搬砖二分法☆☆☆10转盘寿司数据结构/栈/单调栈☆☆☆11小明找位置二分法☆☆☆12提取字符串的最长合法简单数学表达式双指[...]
[...]2024 C卷 100分序号题目知 识 点难易程度1密码输入检测数据结构/栈☆☆☆2分配土地几何问题☆☆☆3找座位逻辑分析☆☆☆4智能成绩表动态条件分析☆☆☆5内存冷热标记多条件排序☆☆☆6螺旋数字矩阵逻辑分析☆☆☆7围棋的气逻辑分析☆☆☆8分割平衡字符串逻辑分析☆☆☆9机器人搬砖二分法☆☆☆10转盘寿司数据结构/栈/单调栈☆☆☆11小明找位置二分法☆☆☆12提取字符串的最长合法简单数学表达式双指[...]
[...]2024 C卷 100分序号题目知 识 点难易程度1密码输入检测数据结构/栈☆☆☆2分配土地几何问题☆☆☆3找座位逻辑分析☆☆☆4智能成绩表动态条件分析☆☆☆5内存冷热标记多条件排序☆☆☆6螺旋数字矩阵逻辑分析☆☆☆7围棋的气逻辑分析☆☆☆8分割平衡字符串逻辑分析☆☆☆9机器人搬砖二分法☆☆☆10转盘寿司数据结构/栈/单调栈☆☆☆11小明找位置二分法☆☆☆12提取字符串的最长合法简单数学表达式双指[...]
[...]序号题目考点难易程度1二叉树计算二叉树前序、中序遍历☆☆☆25G网络建设最小生成树☆☆☆☆3找数字逻辑分析☆☆☆4符号运算数据结构 / 栈☆☆☆5爱吃蟠桃的孙悟空二分法☆☆☆6结队编程暴力枚举 二叉树索树☆☆☆7石头剪刀布游戏逻辑分析☆☆☆8攀登者2逻辑分析☆☆☆9分月饼递归☆☆☆10电脑病毒感染图论 / 单源最短路径(dijkstra☆☆☆11最长连续手牌回溯算法☆☆☆[...]