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%%\n", dp[x][y] * 100);
}
}
int main(){
init();
work();
return 0;
}