pta集合相似度

pta集合相似度

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

输入格式:
输入第一行给出一个正整数N(≤50),是集合的个数。随后N行,每行对应一个集合。每个集合首先给出一个正整数M(≤10000),是集合中元素的个数;然后跟M个[0,10^9 ]区间内的整数。
之后一行给出一个正整数K(≤2000),随后K行,每行对应一对需要计算相似度的集合的编号(集合从1到N编号)。数字间以空格分隔。

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

输入样例:
3
3 99 87 101
4 87 101 5 87
7 99 101 18 5 135 18 99
2
1 2
1 3
输出样例:
50.00%
33.33%

一开始打算用c写结果弄了半天,最后一个点仍然超时……
感觉是查找相同数字的嵌套循环太耗时间了。

#include <stdio.h>
#include <stdlib.h>


float same(int a[],int b[], int lena, int lenb);//找出相同的数返回相同数的个数

int main(void){
    int n,m,i,j,k,temp;
    float x,y;
    int mark = 1;
    int **space,*len,**request;//space储存集合,len存储space的长度,request存储要查询的集合名


    scanf("%d",&n);//输入集合个数
    len = (int*)malloc(n*sizeof(int));
    space = (int **)malloc(n*sizeof(int *));
    for (i = 0;i < n; i++){
        scanf("%d",&len[i]);
        space[i] = (int *)malloc(len[i]*sizeof(int ));
        for(j = 0; j < len[i];j ++){
            scanf("%d",&temp);//输入将要放入集合的数
            if(j > 0){
                for(k = 0; k <= j-1; k ++){
                    if (space[i][k] == temp){
                        len[i]--;
                        mark = 0;
                    }
                }
            }
            if (mark == 0){
                mark = 1;
                j--;
                space[i] = (int *)realloc(space[i], len[i]*sizeof(int ));
            } else{
                space[i][j] = temp;
            }
        }
        space[i] = (int *)realloc(space[i],len[i]*sizeof(int ));
    }
    scanf("%d",&m);
    request = (int**) malloc(m*sizeof(int*));
    for(i = 0; i < m; i++){
        request[i] = (int*)malloc(2*sizeof(int));
        scanf("%d %d",&request[i][0],&request[i][1]);
    }
    for(i = 0; i < m; i++){
        x = same(space[request[i][0]-1],space[request[i][1]-1],len[request[i][0]-1],len[request[i][1]-1]);
        y = len[request[i][0]-1]+len[request[i][1]-1]-x;
        printf("%.2f%%\n",(x/y)*100);
    }
    return 0;
}

float same(int a[],int  b[], int lena, int lenb){
    int i,j;
    float z = 0;
    for(i = 0; i < lena; i++){
        for (j = 0; j < lenb; j++) {
            if (a[i] == b[j]){
                z ++;
            }
        }
    }
    return z;
}

后来放弃了用c……改用Python来写结果不到20行完美通过…………

N = input()  # 输入集合个数
lists = []  # 集合列表
for i in range(int(N)):
	temper = input()  # 输入n个集合
	lists.append(set(list(temper.split())[1:])) # 将n个集合加入集合列表

M = input()
list1 = []  # 要计算的集合组
for i in range(int(M)):
	temper = input()
	list1.append(temper.split())

for i in range(int(M)):
	k = len(lists[int(list1[i][0])-1] & lists[int(list1[i][1])-1])
	z = len(lists[int(list1[i][0])-1] | lists[int(list1[i][1])-1])
	print(str(format(float(k)/float(z)*100,'.2f'))+"%")

最后一句人生苦短我用Python!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值