acwing -- 1459. 奶牛体操
给我们一些排列,问我们在这些排列中,哪些元素的相对位置没有发生变化。
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; }