L2-005 集合相似度 (25 分)
输出格式:
对每一对需要计算的集合,在一行中输出它们的相似度,为保留小数点后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%
思路问题代码(忘记用set的集合)
#include <iostream>
#include <set>
using namespace std;
int Num[52][10002]; //存放所有集合
int main() {
int N, Tmp;
int K[52]; //存放每组集合初始元素个数
cin >> N; //得到集合个数
for (int t = 1; t <= N; t++) {
set<int> s1; //用于为每组集合判别重复元素
cin >> K[t]; //得到当前集合元素个数
int P = K[t];
for (int i = 1; i <= P; i++) {
scanf("%d", &Tmp);
if (s1.insert(Tmp).second) Num[t][i] = Tmp; //非重复元素
else K[t]--; //剔除重复元素 该集合元素总数减1
}
}
int M;
cin >> M; //得到查询次数
while (M--) {
int pos1, pos2, Pass = 0; //Pass用来记录两组集合重复元素个数
cin >> pos1 >> pos2; //得到两个要求比较的集合位置
set<int> s2; //用于判别两组集合重复元素
for (int i = 1; i <= K[pos1]; i++) s2.insert(Num[pos1][i]); //将第一组集合全部插入
for (int i = 1; i <= K[pos2]; i++) if (!s2.insert(Num[pos2][i]).second) Pass++;
double Ret = Pass * 100.0 / (K[pos1] + K[pos2] - Pass);
printf("%.2lf", Ret); cout << "%" << endl;
}
return 0;
}
AC代码
#include <iostream>
#include <set>
using namespace std;
int main() {
int N; cin >> N; //得到集合总数
set<int> s[52];
for (int i = 1; i <= N; i++) {
int K; cin >> K; //得到当前集合元素个数
while (K--) { int Tmp; cin >> Tmp; s[i].insert(Tmp); } //得到所有集合 同时为每个集合剔除重复元素
}
int M; cin >> M; //得到待查询次数
while (M--) {
int pos1, pos2, same = 0; cin >> pos1 >> pos2; //得到两个待比较的集合 same记录两个集合重复元素个数
set<int>::iterator iter;
for (iter = s[pos1].begin(); iter != s[pos1].end(); iter++)
if (s[pos2].find(*iter) != s[pos2].end()) same++; //找到相同元素
double Ret = same * 100.0 / (s[pos1].size() + s[pos2].size() - same); //计算相似度
printf("%.2lf", Ret); cout << "%" << endl;
}
return 0;
}