PAT A1063 Set Similarity (25point(s))

题目链接
注意点:
1.要滤掉集合中的相同元素,因此使用set比较方便。
2.比较两集合时因遍历其中一个集合的每个元素,与另一个集合中的元素比较,用find()来查找时间复杂度可以到O(n(a)logn(b)),如果处理两个集合,时间复杂度会到O(N^2),最后一个样例会超时。
AC代码:

#include<cstdio>
#include<set>
using namespace std;
set<int> sets[55];//集合的集合
int main(){
    int n;
    scanf("%d",&n);//输入集合数
    for(int i=1;i<=n;i++){//建立集合
        int m,t;
        scanf("%d",&m);
        for(int j=0;j<m;j++){
            scanf("%d",&t);
            sets[i].insert(t);
        }
    }
    int query;
    scanf("%d",&query);//查询数
    for(int i=0;i<query;i++){
        int a,b;
        scanf("%d %d",&a,&b);//查询数组对的序号
       int totalnum=sets[a].size(),common=0;
       //totalnum是总元素的个数,即不同元素的个数,common是相同元素的个数
       for(set<int>::iterator it=sets[b].begin();it!=sets[b].end();it++){
           //对b集合中的每个元素进行比较    
            if(sets[a].find(*it)!=sets[a].end()) {
                //该元素在集合a中出现
              common++;//相同元素时加1
        }
        else totalnum++;//否则不同元素数加1
       }
        printf("%.1lf%%\n",(float)common/totalnum*100);
        //输出百分号要用两个%%
        //计算比值
    }
    return 0;
}

贴一下处理两个集合的比较函数。该函数的思想是将两个集合中的元素合并到一个集合中,插入后合并集合大小不变,则说明有相同元素。该算法时间复杂度为O((n(a)+n(b))(log(n(a)+n(b))),会超时。

void compare(int a,int b){
        set<int>::iterator temp;
        set<int>::iterator ita=sets[a].begin();
        set<int>::iterator itb=sets[b].begin();
        while(ita!=sets[a].end()||itb!=sets[b].end()){
            int tempsize=temp.size();
            if(ita!=sets[a].end()) {
                temp.insert(*ita);
                if(temp.size()==tempsize) common++;
                ita++;
            }
             tempsize=temp.size();
            if(itb!=sets[b].end()) {
                temp.insert(*itb);
                if(temp.size()==tempsize) common++;
                itb++;
            }
        }
        printf("%.1lf%%\n",(float)common/temp.size()*100);
        }
发布了81 篇原创文章 · 获赞 0 · 访问量 648

猜你喜欢

转载自blog.csdn.net/weixin_44546393/article/details/105590802