7-9 集合相似度

解法时间复杂度

  1. unordered_map 460ms
  2. set查找 230ms
  3. 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;
}

猜你喜欢

转载自www.cnblogs.com/xyqxyq/p/12302762.html