L2-005 集合相似度

STL map 的遍历

map<int, int>M;
map<int, int>::iterator iter;
for(iter = M.begin();iter != M.end();iter++){}

L2-005 集合相似度

输入格式:
输入第一行给出一个正整数N(≤50),是集合的个数。随后N行,每行对应一个集合。每个集合首先给出一个正整数M(≤10
​4
​​ ),是集合中元素的个数;然后跟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%

Solution

先排序去重,丢map里统计个数就行
插一句,输出 % 打两个%% 就行

Code

#include<iostream>
#include<cstdio>
#include<queue>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<climits>
#include<map>
#include<string>
#define LL long long
#define REP(i, x, y) for(LL i = (x);i <= (y);i++)
using namespace std;
int RD(){
    LL out = 0,flag = 1;char c = getchar();
    while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
    while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
    return flag * out;
    }
const int inf = 5000100, maxn = 10010;
int num, na;
int input[60][maxn];
double dp[60][60];
void init(){
	num = RD();
	REP(i, 1, num){
		input[i][0] = RD();
		REP(j, 1, input[i][0]){
			input[i][j] = RD();
			}
		}
	REP(i, 1, num)REP(j, 1, num)dp[i][j] = -1;
	}
map<int, int>M;
map<int, int>::iterator iter;
int a[maxn], b[maxn];
void get_ans(int x, int y){
	REP(i, 0, input[x][0])a[i] = input[x][i];
	REP(i, 0, input[y][0])b[i] = input[y][i];
	sort(a + 1, a + 1 + a[0]);
	sort(b + 1, b + 1 + b[0]);
	M.clear();
	
	REP(i, 1, a[0])if(i == a[0] || a[i] != a[i + 1])M[a[i]]++;
	REP(i, 1, b[0])if(i == b[0] || b[i] != b[i + 1])M[b[i]]++;
	
	int tot = M.size(), cnt = 0;
	for(iter = M.begin();iter != M.end();iter++)if(iter->second == 2)cnt++;
	dp[x][y] = dp[y][x] = (double)cnt / tot;
	}
void work(){
	na = RD();
	while(na--){
		int x = RD(), y = RD();
		if(dp[x][y] == -1)get_ans(x, y);
		printf("%.2f%%
", dp[x][y] * 100);
		}
	}
int main(){
	init();
	work();
	return 0;
	}

原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/14008521.html