PAT甲级 A1063
1063 Set Similarity (25分)
Given two sets of integers, the similarity of the sets is defined to be N
c
/N
t
×100%, where N
c
is the number of distinct common numbers shared by the two sets, and N
t
is the total number of distinct numbers in the two sets. Your job is to calculate the similarity of any given pair of sets.
Input Specification:
Each input file contains one test case. Each case first gives a positive integer N (≤50) which is the total number of sets. Then N lines follow, each gives a set with a positive M (≤10
4
) and followed by M integers in the range [0,10
9
]. After the input of sets, a positive integer K (≤2000) is given, followed by K lines of queries. Each query gives a pair of set numbers (the sets are numbered from 1 to N). All the numbers in a line are separated by a space.
Output Specification:
For each query, print in one line the similarity of the sets, in the percentage form accurate up to 1 decimal place.
Sample Input:
3
3 99 87 101
4 87 101 5 87
7 99 101 18 5 135 18 99
2
1 2
1 3
Sample Output:
50.0%
33.3%
思路1
在这道题的思路里我觉得可以采用map存储来减少运行时间,事实证明最后一个点仍然超时
#include<iostream>
#include<string>
#include<vector>
#include<cmath>
#include<memory.h>
#include<string>
#include<algorithm>
#include<iomanip>
#include<map>
#include<stack>
#include<queue>;
using namespace std;
class arrays {
public:
int nos;
vector<int> haves;
};
vector<arrays> as;
int main(){
int N;
cin >> N;
for (int i = 0; i < N; i++) {
int num; scanf_s("%d", &num);
arrays temp; temp.nos = num;
for (int j = 0; j < num; j++) {
int tt; scanf_s("%d", &tt);
temp.haves.push_back(tt);
}
as.push_back(temp);
}
int N2; cin >> N2;
for (int i = 0; i < N2; i++) {
int a1, a2; scanf_s("%d%d", &a1, &a2);
arrays ar1 = as[a1 - 1]; arrays ar2 = as[a2 - 1];
int totalno = 0;
int publics = 0;
map<int, int> setst;
map<int, int> sets1;
for (int j = 0; j < ar1.nos; j++) {
int number = ar1.haves[j];
if (setst.find(number) == setst.cend()) {
setst[number] = 1;
totalno++;
}
if (sets1.find(number) == sets1.cend()) {
sets1[number] = 1;
continue;
}
}
for (int j = 0; j < ar2.nos; j++) {
int number = ar2.haves[j];
if (setst.find(number) == setst.cend()) {
setst[number] = 1;
totalno++;
}
if (sets1.find(number) == sets1.cend()) {
continue;
}
else {
if (sets1[number] == 1) {
publics++;
sets1[number] = 0;
}
}
}
double ans = (publics / (totalno * 1.0)) * 100;
cout << fixed << setprecision(1) << ans << "%" << '\n';
}
}
思路2
用了set和stl的模板还是超时
#include<iostream>
#include<string>
#include<vector>
#include<cmath>
#include<memory.h>
#include<string>
#include<algorithm>
#include<iomanip>
#include<map>
#include<stack>
#include<queue>;
#include<set>;
#include <stdio.h>
#include<iterator>
using namespace std;
class arrays {
public:
int nos;
set<int> haves;
};
vector<arrays> as;
int main() {
int N;
scanf("%d", &N);
for (int i = 0; i < N; i++) {
int num; scanf("%d", &num);
arrays temp; temp.nos = num;
for (int j = 0; j < num; j++) {
int tt; scanf("%d", &tt);
temp.haves.insert(tt);
}
as.push_back(temp);
}
int N2; cin >> N2;
for (int i = 0; i < N2; i++) {
int a1, a2; scanf("%d%d", &a1, &a2);
arrays ar1 = as[a1 - 1]; arrays ar2 = as[a2 - 1];
set<int> publics;
set<int> unions;
set_intersection(ar1.haves.begin(), ar1.haves.end(), ar2.haves.begin(), ar2.haves.end(), inserter(publics, publics.begin()));
set_union(ar1.haves.begin(), ar1.haves.end(), ar2.haves.begin(), ar2.haves.end(), inserter(unions, unions.begin()));
double ans = (publics.size() / (unions.size() * 1.0)) * 100;
printf("%.1f%%\n", ans);
}
}
思路3
看了其他博主的代码 原来set直接两个寻找就能过
直接复制了一个博主的AC代码
#include <bits/stdc++.h>
using namespace std;
int main(int argc, char const *argv[])
{
int n;
scanf("%d", &n);
vector<set<int> > s(n);
for (int i = 0; i < n; ++i)
{
int num;
scanf("%d", &num);
int temp;
for (int j = 0; j < num; ++j)
{
scanf("%d", &temp);
s[i].insert(temp);
}
}
int k;
scanf("%d", &k);
int a, b;
set<int>:: iterator it;
for (int i = 0; i < k; ++i)
{
scanf("%d%d", &a, &b);
int Nc=0, Nt=s[b-1].size();
for(it=s[a-1].begin(); it!=s[a-1].end(); it++)
{
if(s[b-1].find(*it)==s[b-1].end()) Nt++;
else Nc++;
}
float anw = (float)(Nc*100)/(float)Nt;
printf("%.1f%%\n", anw);
}
return 0;
}