1 条题解
-
0
方法思路
- 这道题要求我们从牌堆中选取5张牌构成同花顺,每个同花顺得1分,问最多能得多少分。
- 首先,按照花色将牌分组,然后在每个花色内寻找连续的5张牌。
- 对于每个花色,我们需要:
- 将该花色的所有牌按数值排序
- 使用滑动窗口找出所有可能的连续5张牌
- 对于每个找到的同花顺,计算能组成的数量(取决于5张牌中数量最少的那种)
- 关键点:当找到一个同花顺后,需要将使用过的牌从牌堆中减去,因为每张牌只能使用一次
代码实现
Java
import java.util.*; import java.io.*; public class Main { static class Poker { int digital; int count; public Poker(int digital, int count) { this.digital = digital; this.count = count; } } public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine()); // 使用TreeMap按数值排序 Map<Character, TreeMap<Integer, Integer>> mp = new HashMap<>(); mp.put('S', new TreeMap<>()); mp.put('H', new TreeMap<>()); mp.put('D', new TreeMap<>()); mp.put('C', new TreeMap<>()); StringTokenizer st; for (int i = 0; i < n; i++) { st = new StringTokenizer(br.readLine()); int x = Integer.parseInt(st.nextToken()); int y = Integer.parseInt(st.nextToken()); char ch = st.nextToken().charAt(0); mp.get(ch).put(x, y); } long res = 0; // 处理每种花色 for (Map.Entry<Character, TreeMap<Integer, Integer>> entry : mp.entrySet()) { TreeMap<Integer, Integer> cards = entry.getValue(); // 如果牌数小于5,无法组成同花顺 if (cards.size() < 5) continue; // 将牌值转换为列表,以便更快地访问 List<Integer> values = new ArrayList<>(cards.keySet()); for (int i = 0; i <= values.size() - 5; i++) { // 检查是否连续 boolean isConsecutive = true; for (int j = 0; j < 4; j++) { if (values.get(i + j + 1) != values.get(i + j) + 1) { isConsecutive = false; // 优化:直接跳到不连续的位置 i = i + j; break; } } if (isConsecutive) { // 找到最小牌数 int minCount = Integer.MAX_VALUE; for (int j = 0; j < 5; j++) { minCount = Math.min(minCount, cards.get(values.get(i + j))); } // 更新结果 res += minCount; // 更新剩余牌数 for (int j = 0; j < 5; j++) { int value = values.get(i + j); cards.put(value, cards.get(value) - minCount); } } } } System.out.println(res); } }
Python
def max_score(cards): # 按花色分组 suits = {'S': [], 'H': [], 'D': [], 'C': []} for value, count, suit in cards: suits[suit].append((value, count)) total_score = 0 # 处理每种花色 for suit, cards_list in suits.items(): # 如果牌数小于5,无法组成同花顺 if len(cards_list) < 5: continue # 将该花色的所有牌按数值排序 cards_list.sort() i = 0 while i <= len(cards_list) - 5: dig = cards_list[i][0] mark = cards_list[i][1] flag = True j = i + 1 # 检查是否能形成连续5张牌 for j in range(i + 1, i + 5): if j < len(cards_list) and cards_list[j][0] == dig + 1: mark = min(mark, cards_list[j][1]) # 求最小同花顺数量 dig = cards_list[j][0] else: flag = False break # 如果找到同花顺 if flag: total_score += mark # 减去已使用的牌 for j in range(i + 1, i + 5): cards_list[j] = (cards_list[j][0], cards_list[j][1] - mark) else: # 优化:直接跳到不连续的位置 i = j - 1 i += 1 return total_score # 读取输入 n = int(input()) cards = [] for _ in range(n): value, count, suit = input().split() cards.append((int(value), int(count), suit)) # 计算并输出结果 print(max_score(cards))
C++
#include <iostream> #include <vector> #include <unordered_map> #include <algorithm> using namespace std; struct Poker { int digital; int count; Poker() {} Poker(int x, int y) : digital(x), count(y) {} }; int main() { int n; cin >> n; unordered_map<char, vector<Poker>> mp; for (int i = 0; i < n; i++) { int x, y; char ch; cin >> x >> y >> ch; mp[ch].push_back(Poker(x, y)); } long long res = 0; // 处理每种花色 for (auto& pokarray : mp) { // 如果牌数小于5,无法组成同花顺 if (pokarray.second.size() < 5) continue; // 将该花色的所有牌按数值排序 sort(pokarray.second.begin(), pokarray.second.end(), [](const Poker& a, const Poker& b) { return a.digital < b.digital; }); int i = 0; while (i <= pokarray.second.size() - 5) { int dig = pokarray.second[i].digital; int mark = pokarray.second[i].count; bool flag = true; int j = i + 1; // 检查是否能形成连续5张牌 for (; j < i + 5; j++) { if (pokarray.second[j].digital == dig + 1) { mark = min(mark, pokarray.second[j].count); // 求最小同花顺数量 dig = pokarray.second[j].digital; } else { flag = false; break; } } // 如果找到同花顺 if (flag) { res += mark; // 减去已使用的牌 for (int j = i + 1; j < i + 5; j++) { pokarray.second[j].count -= mark; } } else { // 优化:直接跳到不连续的位置 i = j - 1; } i++; } } cout << res << endl; return 0; }
- 1
信息
- ID
- 89
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 5
- 标签
- 递交数
- 8
- 已通过
- 1
- 上传者