PAT 1063. Set Similarity

每读入一个数集,就要把集合中重复的数字去掉,保证单个集合中每个元素都是distinct的。

这样,计算两个数集的similarity值的时候,只需要计算两个集合的交集,也就是它们之间的公共的元素个数c,而答案就等于c/(集合1的成员数+集合2的成员数-c)。

为了加快计算公共元素的速度,我把每个集合都排序过,每个集合中的元素都是升序排列的,所以检验一个元素是否为某个集合的成员时,可以用二分查找。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int N=10005;
typedef struct sett{
	int shu[N];
	int num;
	sett(){num=0;}
	void inpu(){
		int i,t[N],n;
		scanf("%d",&n);
		if(n<=0)return;
		for(i=0;i<n;i++)
			scanf("%d",&t[i]);
		sort(t,t+n);
		shu[0]=t[0];
		num=1;		
		for(i=1;i<n;i++)
			if(t[i]>t[i-1])
				shu[num++]=t[i];
	}
	int find(int x){
		if(num<=0)return -1;
		int lf=0,rt=num-1,mid=(lf+rt)/2;
		if(x<shu[lf]||x>shu[rt])return -1;
		while(1){
			if(shu[mid]==x)return mid;
			if(lf==rt)return -1;
			if(shu[mid]<x)
				lf=mid+1;
			else if(shu[mid]>x)
				rt=mid;
			mid=(lf+rt)/2;
		}
	}
}sett;
sett se[55];
int n;
double ans[55][55];
void func(int a,int b){
	if(ans[a][b]!=-1){
		printf("%.1lf%%\n",ans[a][b]);
		return;
	}
	double com=0,dis=se[a].num+se[b].num;
	int i;
	for(i=0;i<se[b].num;i++){
		if(se[a].find(se[b].shu[i])>=0){
			com+=1;
			dis-=1;
		}
	}
	ans[a][b]=(com/dis)*100.0;
	printf("%.1lf%%\n",ans[a][b]);
}
int main(){
	int i,j;
	scanf("%d",&n);
	for(i=0;i<n;i++)
		se[i].inpu();
	for(i=0;i<55;i++)
		for(j=0;j<55;j++)
			ans[i][j]=-1;
	int m,a,b;
	scanf("%d",&m);
	while(m--){
		scanf("%d%d",&a,&b);
		func(a-1,b-1);
	}
return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值