题目
题目描述
研究证明,有一个因素在两头奶牛能否作为朋友和谐共处这方面比其他任何因素都来得重要——是不是喜欢同一种口味的冰激凌!
F a r m e r J o h n \tt{Farmer\; John} FarmerJohn 的 N ( 2 ≤ N ≤ 50 , 000 ) N(2≤N≤50,000) N(2≤N≤50,000) 头奶牛各自列举了最喜欢的五种冰激凌口味的清单。为使这个清单更加精炼,每种可能的口味用一个不超过 1 0 6 10^6 106 的正整数 X X X 表示。如果两头奶牛的清单上有至少一种共同的冰激凌口味,那么二者可以和谐共处。
请求出不能和谐共处的奶牛的对数。
输入格式
输入的第一行包含
N
N
N 。以下
N
N
N 行每行包含
5
5
5 个整数(各不相同),表示一头奶牛最喜欢的冰激凌口味。
输出格式
输出不能和谐共处的奶牛的对数。
数据范围与约定
见题目描述。
思路
发现冰淇淋的种类只有 5 5 5 种,直接 容斥 走起!
用 u n o r d e r e d m a p \tt{unordered\;map} unorderedmap 存储,不要使用 m a p \tt{map} map (否则 T T T 死你娃)。
代码
#include <cstdio>
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
inline int readint(){
int a = 0, f = 1; char c = getchar();
for(; c<'0' or c>'9'; c=getchar())
if(c == '-') f = -1;
for(; '0'<=c and c<='9'; c=getchar())
a = (a<<3)+(a<<1)+(c^48);
return a*f;
}
inline void writeint(long long x){
if(x > 9) writeint(x/10);
putchar((x%10)^48);
} // actually unsigned long long
unordered_map<string,int> cnt;
int a[5]; string toString[1000001];
int main(){
int n = readint();
long long ans = 1ll*n*(n-1)>>1;
for(int i=0; i<10; ++i)
toString[i] = char(i+'0');
for(int i=10; i<=1000000; ++i)
toString[i] = toString[i/10]+char(i%10+'0');
for(int i=1; i<=n; ++i){
for(int j=0; j<5; ++j)
a[j] = readint();
/* 规定集合中的元素递增才不会出问题 */
for(int j=1; j<5; ++j)
for(int k=0; k<5-j; ++k)
if(a[k] > a[k+1])
swap(a[k],a[k+1]);
for(int S=1; S<(1<<5); ++S){
string id = ""; int sgn = 1;
for(int j=0; j<5; ++j)
if(S>>j&1){
id += '#'; // 特殊分割符
id += toString[a[j]];
sgn = -sgn;
}
ans += sgn*cnt[id];
++ cnt[id];
}
}
writeint(ans);
putchar('\n');
return 0;
}