题目链接

纸牌游戏

题目描述

Alex 与 Bob 进行纸牌游戏。Alex 有两张牌 ,Bob 有两张牌 。 游戏分两回合,每回合双方随机翻开一张未翻开的牌比大小。牌面大者赢下该回合,相等则平局。 两回合后,赢得回合数更多的一方获胜。若双方赢得回合数相同,则游戏平局。

已知四张牌的具体数字,求 Alex 最终获胜的不同翻牌顺序有多少种。

解题思路

本题要求我们计算在所有可能的翻牌顺序中,Alex 获胜的次数。

首先,我们分析“翻牌顺序”的构成。

  • 设 Alex 的牌为 ,Bob 的牌为
  • 第一回合,Alex 可以出 (2种选择),Bob 可以出 (2种选择)。
  • 第一回合的牌一旦确定,第二回合的牌也就随之确定了。
  • 因此,总共有 种不同的翻牌顺序。

这 4 种顺序可以归结为两种基本的牌局配对

  1. 配对一:Alex 的 对阵 Bob 的 ,同时 对阵
    • 这对应了两种翻牌顺序:
      • 第一回合 vs ,第二回合 vs
      • 第一回合 vs ,第二回合 vs
    • 这两种顺序的回合胜负情况完全相同,因此游戏最终结果也相同。
  2. 配对二:Alex 的 对阵 Bob 的 ,同时 对阵
    • 这同样对应了两种翻牌顺序。
    • 这两种顺序的游戏最终结果也相同。

因此,我们的解题策略可以简化为:

  1. 分别计算上述两种配对下的游戏结果。
  2. 如果一种配对能让 Alex 获胜(即 Alex 在该配对的两场比赛中赢得的回合数多于 Bob),那么就给最终的获胜顺序计数器加上 2。
  3. 将两种配对的结果相加,就是最终答案。

为了方便处理,我们可以先将 Alex 和 Bob 的手牌进行排序,例如 Alex 的牌为 ,Bob 的牌为 。然后分析以下两种配对:

  • 配对一:( vs ) 和 ( vs )
  • 配对二:( vs ) 和 ( vs )

对每个配对,计算 Alex 的胜场数是否大于 Bob 的胜场数即可。

代码

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

int get_alex_wins(int a1, int a2, int b1, int b2) {
    int alex_score = 0;
    int bob_score = 0;
    if (a1 > b1) alex_score++;
    if (b1 > a1) bob_score++;
    if (a2 > b2) alex_score++;
    if (b2 > a2) bob_score++;
    return alex_score > bob_score ? 2 : 0;
}

void solve() {
    int a1, a2, b1, b2;
    cin >> a1 >> a2 >> b1 >> b2;
    
    int total_wins = 0;
    
    // 配对一: a1 vs b1, a2 vs b2
    total_wins += get_alex_wins(a1, a2, b1, b2);
    
    // 配对二: a1 vs b2, a2 vs b1
    total_wins += get_alex_wins(a1, a2, b2, b1);

    cout << total_wins << endl;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}
import java.util.Scanner;

public class Main {

    private static int getAlexWins(int a1, int a2, int b1, int b2) {
        int alexScore = 0;
        int bobScore = 0;
        if (a1 > b1) alexScore++;
        if (b1 > a1) bobScore++;
        if (a2 > b2) alexScore++;
        if (b2 > a2) bobScore++;
        
        return alexScore > bobScore ? 2 : 0;
    }

    public static void solve(Scanner sc) {
        int a1 = sc.nextInt();
        int a2 = sc.nextInt();
        int b1 = sc.nextInt();
        int b2 = sc.nextInt();

        int totalWins = 0;

        // 配对一: a1 vs b1, a2 vs b2
        totalWins += getAlexWins(a1, a2, b1, b2);
        
        // 配对二: a1 vs b2, a2 vs b1
        totalWins += getAlexWins(a1, a2, b2, b1);
        
        System.out.println(totalWins);
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int t = sc.nextInt();
        while (t-- > 0) {
            solve(sc);
        }
    }
}
def get_alex_wins(a1, a2, b1, b2):
    alex_score = 0
    bob_score = 0
    if a1 > b1:
        alex_score += 1
    elif b1 > a1:
        bob_score += 1
    
    if a2 > b2:
        alex_score += 1
    elif b2 > a2:
        bob_score += 1
        
    return 2 if alex_score > bob_score else 0

def solve():
    a1, a2, b1, b2 = map(int, input().split())
    
    total_wins = 0
    
    # 配对一: a1 vs b1, a2 vs b2
    total_wins += get_alex_wins(a1, a2, b1, b2)
    
    # 配对二: a1 vs b2, a2 vs b1
    total_wins += get_alex_wins(a1, a2, b2, b1)
    
    print(total_wins)

t = int(input())
for _ in range(t):
    solve()

算法及复杂度

  • 算法:模拟 / 枚举
  • 时间复杂度:对于每个测试用例,我们只进行常数次比较。因此,时间复杂度是
  • 空间复杂度:,只需要存储几个变量。