分类:其他 难度:1
题意:给出p,t两个数,p个人,t棵树,给出一堆i,j两个数的集合,表示第i个人听到第j棵树倒下。听到倒下的树的集合完全相同的人为一组,问有几组人
分析:
解法一:简单思路,给一个矩阵re[100][100],re[i][j]存储第i个人听到第j棵树倒下,然后遍历每两个人,比较是否相同,时间复杂度O(p^2 * t),空间复杂度O(p*t)
解法二:考虑每个人听到树倒下的集合不使用数组,而用两个unsigned long long 型变量,分别标记前50位和后50位,然后两两比较,时间O(p^2),空间O(p)
解法三:再优化两两比较的时间,通过stl的set改进,遍历每个人的信息,加入set中,由于set没有重复变量,所以最后统计set的大小即可,时间O(p),空间O(p)
不过由于这个题数据规模很小,p,t<100,所以用那种方法都可以,解法三由于引入set,所以空间复杂度的常数比解法二大
代码,为解法三
#include<cstdio>
#include<set>
#include<cstring>
using namespace std;
set<pair<unsigned long long, unsigned long long> > re;
unsigned long long da[110][2];
int main()
{
//freopen("2419.txt","r",stdin);
//freopen("2419.out","w",stdout);
int p,t;
scanf("%d%d",&p,&t);
memset(da,0,sizeof(da));
int tp,tt;
while(scanf("%d%d",&tp,&tt)!=EOF)
{
if(tt<50)
da[tp][0] |= (1<<(tt-1));
else
da[tp][1] |= (1<<(tt-51));
}
for(int i=1; i<=p; i++)
{
re.insert(make_pair(da[i][0],da[i][1]));
}
printf("%d\n",re.size());
}