05_Cow_Gymnastics

问题描述

USACO 2019 December Contest, Bronze Problem 1. Cow Gymnastics https://usaco.org/index.php?page=viewproblem2&cpid=963

奶牛们正在进行体操训练,Bessie 记录了 K 次训练课中 N 头奶牛的排名。我们需要找出所有”一致”的奶牛对,即其中一头奶牛在每次训练课中都表现得比另一头要好。

0 ≤ N ≤ 20,1 ≤ K ≤ 10

样例

输入:

3 4
4 1 2 3
4 1 3 2
4 2 1 3

输出 :

4

思路

对于任意一对奶牛 (i, j),它们的关系可能有三种情况: 1. i 在每次训练课中都比 j 表现好 2. j 在每次训练课中都比 i 表现好 3. 互有胜负(有时 ij 好,有时 ji 好) 只有前两种情况才符合”一致”的定义。

我们可以创建一个二维布尔数组,该数组表示在任何时间点奶牛 A 的排名是否高于奶牛 B 。在读取完所有排名后,对于所有 $\frac{N(N-1)}{2}$ 对,我们设置 b[A][B] = true

然后我们遍历所有对,检查它们是否满足条件。如果两个都为真,那么这对在某个时间点改变了排名顺序。如果只有一个为真,那么这对保持了一致的顺序。因此,需要 b[A][B]b[B][A] 中至少有一个为真,可以用异或操作 a[i][j] ^ a[j][i] 来检测。

复杂度分析

时间复杂度:O(K × N²) 空间复杂度:O(N²) # 代码

#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    freopen("gymnastics.in", "r", stdin);
    freopen("gymnastics.out", "w", stdout);
    int k, n;
    cin >> k >> n;
    
    vector<vector<bool>>a(n, vector<bool>(n));
    for(int tt = 0; tt < k; tt++){
        vector<int> b(n);
        for(int& x:b){
            cin >> x;
            x--;
        }
        for(int i = 0; i < n; i++){
            for(int j = i+1; j < n; j++){
                a[b[i]][b[j]] = true;
            }
        }
    }
    
    int ans = 0;
    for(int i = 0; i < n; i++){
        for(int j = i+1; j < n; j++){
            ans += a[i][j] ^ a[j][i];
        }
    }
    cout << ans;
    return 0;
}

05_Cow_Gymnastics
https://mingsm17518.github.io/2025/11/20/algorithm/Complete_Search/05_Cow_Gymnastics/
作者
Ming
发布于
2025年11月20日
更新于
2026年2月2日
许可协议