Pat CCCC GPLT L2-005 集合相似度 容斥原理

L2-005. 集合相似度  容斥!!

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越

给定两个整数集合,它们的相似度定义为:Nc/Nt*100%。其中Nc是两个集合都有的不相等整数的个数,Nt是两个集合一共有的不相等整数的个数。你的任务就是计算任意一对给定集合的相似度。

输入格式:

输入第一行给出一个正整数N(<=50),是集合的个数。随后N行,每行对应一个集合。每个集合首先给出一个正整数M(<=104),是集合中元素的个数;然后跟M个[0, 109]区间内的整数。

之后一行给出一个正整数K(<=2000),随后K行,每行对应一对需要计算相似度的集合的编号(集合从1到N编号)。数字间以空格分隔。

输出格式:

对每一对需要计算的集合,在一行中输出它们的相似度,为保留小数点后2位的百分比数字。

思路:

看见集合,想到C4测评机比较糟糕,想手写一个简单的set,但是还是忍不住用了STL;

Stl的set自动去重,故这个集合在形式上与数学上的集合一致。由容斥原理(其实可以画一个文氏图(好像还叫韦恩图)),对于两个集合A,B有

card(A∩B)=card(A)+card(B)-card(A∪B),所以只要求出交集大小或并集大小即可;

这里还是用std::set,直接搞出A∪B这个集合,再用std::set的.size()方法即可;

//A∪B代表A,B中所有的不同因子组成的集合

//A∩B代表A,B中所有共有的不同因子组成的集合

//代码中for(A i:collection<A>){}就是遍历这个容器中所有的元素,i不是下标而是元素!!!for each循环只能遍历这个collection不能修改其中的元素!!!

槽点:

刚开始,因为本人编译器不支持c++14,所以尴尬的过不了编译,就直接交了,结果错误,发现‘%’这个东西没有输出出来,果断putchar(),又把换行符忘了,好不容易不wa了,最后一组数据超时于是把

{

       ans=a[n].size()+a[t].size()-un.size();

       ans/=un.size();

        ans*=100;

}

改成

{

        ans=100*(a[n].size()+a[t].size()-un.size());

        ans/=un.size();

}

就过了。

代码:

#include<set>

#include<cstdio>
using namespace std;
set<int> a[55];
set<int> un;
int main() {
    int n,m,t;
    scanf("%d",&n);
    for(int i=1;i<=n;++i){
        scanf("%d",&m);
        while(m--){
            scanf("%d",&t);
            a[i].insert(t);
        }
    }
    scanf("%d",&m);
    while(m--){
        scanf("%d%d",&n,&t);
        un.clear();
        for(int i:a[n]){
            un.insert(i);
        }
        for(int i:a[t]){
            un.insert(i);
        }
        double ans=100.0*(a[n].size()+a[t].size()-un.size());
        ans/=un.size();
        printf("%.2lf",ans);
        putchar('%');
        putchar('\n');
    }
    return 0;
}

posted @ 2018-03-05 11:26  可爱如我  阅读(143)  评论(0编辑  收藏  举报