acwing -- 1459. 奶牛体操

发布时间 2023-07-11 11:52:36作者: 深渊之巅

 给我们一些排列,问我们在这些排列中,哪些元素的相对位置没有发生变化。

 

1.利用哈希

我们对每个数据对(i, j)进行哈希处理 v = i * 100 + j;

然后对剩下的排列进行枚举,看看有没有 j * 100 + i == v的,如果有,就说明所有排列中即出现了(i, j) 也出现了(j, i)不满足条件,删除。

最终答案即为哈希表的大小。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<unordered_set>

using namespace std;

const int N = 30;

int n, k;
int arr[N];
unordered_set<int> mp;

int main() {
    cin >> k >> n;
    
    k -- ;
    for(int i = 0; i < n; i ++ ) {
        cin >> arr[i];
    }
    
    for(int i = 0; i < n; i ++ ) {
        for(int j = i + 1; j < n; j ++ ) {
            mp.insert(arr[i] * 100 + arr[j]); //存取键值对<i, j> i = v / 100, j = v % 100
        }
    }
    
    while(k -- ) {
        for(int i = 0; i < n; i ++ ) {
            cin >> arr[i];
        }
        for(int i = 0; i < n; i ++ ) {
            for(int j = i + 1; j < n; j ++ ) {
                if(mp.count(arr[j] * 100 + arr[i])) {
                    mp.erase(arr[j] * 100 + arr[i]);
                }
            }
        }
    }
    
    cout << mp.size() << endl;
    
    return 0;
}

 

方法2:图

采用邻接矩阵,首先对第一次出现的所有数对加边。遍历之后出现的所有数对,若出现了反相边,则不满足条件。将两条边都删除。

最终答案即为边的数量。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 30;

int n, k;
int a[N];
int g[N][N];

int main() {
    cin >> k >> n;
    
    while(k -- ) {
        for(int i = 0; i < n; i ++ ) {
            cin >> a[i];
            for(int j = 0; j < i; j ++ ) {
                if(g[a[i]][a[j]] != 0) {
                    g[a[i]][a[j]] = g[a[j]][a[i]] = -1;
                } else {
                    g[a[j]][a[i]] = 1;
                }
            }
        }
    }
    
    int res = 0;
    for(int i = 1; i <= n; i ++ ) {
        for(int j = 1; j <= n; j ++ ) {
            if(g[i][j] == 1) res ++ ; 
        }
    }
    
    cout << res << endl;
    
    return 0;
}