PAT-甲级真题1063 Set Similarity (25分)

1063 Set Similarity (25分)

题目链接
1.题目分析:给定几个集合,如何计算出一对集合(两个)的相似性。即用两个集合的交集元素个数除以两个集合的并集元素个数。
2.思路分析:
方法1:用set集合数组分别存放每一个集合,然后对于待查询的a,b集合求它们的交集元素个数和并集元素个数。开始没有关注时间复杂度,在计算交集和并集的时候采用将两个集合的元素存放在新的set集合里面,然后得到并集元素个数。然后用原来两个集合的元素总和减去现在的并集元素个数就是交集元素个数了。这样的算法在小规模数据还可行,但是不能符合本题要求所以超时!!
代码:`

#include <bits/stdc++.h>

using namespace std;
//下面这个算法超时
int main()
{
    int n;
    double result=0.0;
    scanf("%d",&n);
    set<int> st[n];//set二位数组,用来存放初次集合
    for(int i=0; i<n; i++) //第i个集合
    {
        int m=0,x;
        scanf("%d",&m);//集合中包含的元素个数
        for(int j=0; j<m; j++)
        {
            scanf("%d",&x);
            st[i].insert(x);
        }
    }
    int k,a,b,nt=0,nc=0;
    scanf("%d",&k);//要求查询的组数
    for(int i=0; i<k; i++)
    {
        scanf("%d%d",&a,&b);
        result=0;
        int nt=st[a-1].size()+st[b-1].size();//未合并前两个集合的长度之和
        set<int> st2;
        for(set<int>::iterator it=st[a-1].begin(); it!=st[a-1].end(); it++)
        {
            st2.insert(*it);
        }
        for(set<int>::iterator it=st[b-1].begin(); it!=st[b-1].end(); it++)
        {
            st2.insert(*it);
        }
        int nc=0;
        nc=nt-st2.size();//nc
        result=(double)nc/st2.size();
        printf("%.1f%%\n",result*100);

    }
    return 0;
}

方法2:参考算法笔记算法,用遍历集合a,然后在集合b中找相应的元素。如果在b’中找到该元素,则交集个数加一;如果没有找到则并集个数加一(并集初始值为b的元素个数和)。这样就可以找出需要的两个结果。然后格式化输出即可。
~~注意%号输出时,必须%%才可正常输出%哦。

~~
AC代码:

#include <bits/stdc++.h>
 
using namespace std;
const int N=55;
set<int> st[N];
void compare(int x,int y){
    int tonum=st[y].size(),samenum=0;
    //遍历集合st[x];
    for(set<int>::iterator it=st[x].begin();it!=st[x].end();it++){
    if(st[y].find(*it)!=st[y].end()) //在y集合中找到该元素
    samenum++;//交集数+1
    else tonum++;//并集数+1
    }
    printf("%.1f%%\n",samenum*100.0/tonum);
}
int main(){
    int n,k,x,q,a,b;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&k);
        for(int j=0;j<k;j++){
            scanf("%d",&x);
            st[i].insert(x);//添加x到st[i]中
        }
    }
    scanf("%d",&q);
    for(int i=0;i<q;i++){
        scanf("%d%d",&a,&b);
        compare(a,b);
    }
    return 0;
 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值