PAT甲级 1063 Set Similarity (25 分)

一、暴力解法(21分)

\quad暴力解法就是创建N个集合set,因为集合保证了元素不重复,依次往每个集合中insert数字即可。统计相同元素和所有不同元素个数时可以用map完成,即map中某个元素出现次数为2,那么这是公共元素;map中所有元素个数为不同数字个数。这样做会导致最后一个测试点超时。
PAT甲级 1063 Set Similarity (25 分)
\quad程序如下:

#include <bits/stdc++.h>
using namespace std;

set<int> s[50];

void solve(set<int> &s1, set<int> &s2)
{
	map<int, int> m;
	set<int>:: iterator it1, it2;
	for(it1=s1.begin(); it1!=s1.end(); it1++)
	{
		m[*it1]++;
	}
	for(it2=s2.begin(); it2!=s2.end(); it2++)
	{
		m[*it2]++;
	}

	int Nc = 0, Nt = 0;
	map<int, int>:: iterator it;
	for(it=m.begin(); it!=m.end(); it++)
	{
		Nt ++;
		if(it->second==2) Nc ++;  // 表示这个数在两个集合中都出现过
	}
	float res = (float)(Nc*100)/(float)Nt;
	printf("%.1f%%\n", res);
	return;
}

int main(int argc, char const *argv[])
{
	int n;
	scanf("%d", &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;
	for (int i = 0; i < k; ++i)
	{
		scanf("%d%d", &a, &b);
		solve(s[a-1], s[b-1]);
	}
	return 0;
}

二、就在集合内查找是否包含另一个集合内元素

\quad我感觉这种常规暴力会超时,没想到set的find函数优化很好,竟然可以过!震惊!!!就直接对a集合内元素遍历,查找b集合内是否包含此元素即可。如果不包含,则返回sb.end(),即sb.find(s1_item)==sb.end()表示sb集合内不包含元素s1_item。完整程序如下:

#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;
}

PAT甲级 1063 Set Similarity (25 分)