7-9 集合相似度
解法时间复杂度
- unordered_map 460ms
- set查找 230ms
- set的交集函数 120ms
解法一
这题最开始一直卡,也没想到打表,用了个unordered_map写,复杂度是 n^2 /2 * 2m ,也就是 n^2*m ,我还自以为这是最快的,不打表的时候直接炸裂,后来打表好了。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+10;
int a[52][10010];
double slove(int n1,int n2) {
unordered_map<int,int> cache;
int nt=0,nc=0;
for (int i=1;i<=a[n1][0];i++) {
if (!cache[a[n1][i]]) {
nt++;
cache[a[n1][i]]=1;
}
}
for (int i=1;i<=a[n2][0];i++) {
int t=cache[a[n2][i]];
if (!t) {
nt++;
cache[a[n2][i]]=5;
}
else if (t==1) {
nc++;
cache[a[n2][i]]=2;
}
}
return (double)nc/(double)nt*(100.0);
}
double f[52][52];
int main() {
int n,m,k;
scanf("%d",&n);
for (int i=1;i<=n;i++) {
scanf("%d",&a[i][0]);
for (int j=1;j<=a[i][0];j++) {
scanf("%d",&a[i][j]);
}
}
for (int i=1;i<=n;i++) {
for (int j=i+1;j<=n;j++) {
f[i][j]=f[j][i]=slove(i,j);
}
}
scanf("%d",&k);
int n1,n2;
while (k--) {
scanf("%d%d",&n1,&n2);
printf("%.2lf%\n",f[n1][n2]);
}
return 0;
}
解法二
从一个set里面找另一个set中有的数字并计数
#include <bits/stdc++.h>
using namespace std;
set<int>ss[100];
int aa, bb, n, m, t;
void solve(int a, int b){
int same = 0;
set<int>::iterator it;
for(it = ss[a].begin(); it != ss[a].end(); it++){
if(ss[b].find(*it) != ss[b].end())same++;
}
int sum = ss[a].size() + ss[b].size();
int cnt = sum - same;
printf("%.2lf\%\n",same*1.0/cnt*100);
}
int main(){
// ios::sync_with_stdio(false);
cin >> n;
for(int i = 0 ; i < n ;i++)
{
cin >> t;
for(int j = 0 ; j < t ; j++){
scanf("%d",&aa);
ss[i].insert(aa);
}
}
cin >> m;
for(int i = 0 ; i < m ; i++){
scanf("%d%d",&aa,&bb);
aa--;
bb--;
solve(aa,bb);
}
return 0;
}
解法三
set的交并差集函数,这个居然是最快的,内置函数牛批
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+10;
set<int> st[55];
int main() {
int n,tmp,m;
scanf("%d",&n);
for (int i=1;i<=n;i++) {
scanf("%d",&m);
for (int j=1;j<=m;j++) {
scanf("%d",&tmp);
st[i].insert(tmp);
}
}
int k,n1,n2;
scanf("%d",&k);
while (k--) {
scanf("%d%d",&n1,&n2);
set<int> res;
set_intersection(st[n1].begin(),st[n1].end(),st[n2].begin(),st[n2].end(),inserter(res,res.begin()));
int nc=res.size();
int nt=st[n1].size()+st[n2].size()-res.size();
printf("%.2lf%\n",100.0*nc/nt);
}
return 0;
}