题意:给出n个人,m对朋友关系,其中带负号的表示女孩。然后给出k对查询a,b,要求找出所有a的同性别好友c,以及b的同性别好友d,且c和d又是好友关系。输出所有满足条件的c和d,按c的升序输出,若c编号相同则按d的升序输出。
思路:其实不难,30分的题有点被唬住了。
对于每一个查询a,b,先分别找出a同性好友friend[a],b的同性好友friend[b],然后在friend[a]和friend[b]中找出具有朋友关系的c,d即可。注意,根据题意,-0000和0000是不一样的,若以int类型数据读入,则均表示为0,从而无法区别性别,因此读入数据应该以字符串的类型读入。两者性别是否一致可通过其字符串的长度是否一致来区别。最后,若a,b为同性时,存在a的好友就是b,或b的好友就是a的特殊情况,应该排除掉。因为a要向b联系必须通过两个中间人!
代码:
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <unordered_map> #include <map> #include <set> #include <vector> using namespace std; unordered_map<int,unordered_map<int,bool>> mp;//表示朋友关系的映射 map<int,set<int>> friendOfBoy,friendOfGirl; int main() { //freopen("pat.txt","r",stdin); int n,m,k; scanf("%d%d",&n,&m); char a[10],b[10]; for(int i=0;i<m;i++){ scanf("%s%s",a,b); int u=abs(atoi(a)), v=abs(atoi(b)); mp[v][u]=mp[u][v]=true; if(strlen(a)==strlen(b)){ if(a[0]=='-'){ friendOfGirl[u].insert(v); friendOfGirl[v].insert(u); }else{ friendOfBoy[u].insert(v); friendOfBoy[v].insert(u); } } } scanf("%d",&k); for(int i=0;i<k;i++){ set<int> friendA,friendB; vector<pair<int,int>> ans; scanf("%s%s",a,b); int u=abs(atoi(a)), v=abs(atoi(b)); if(strlen(a)==strlen(b)){ if(a[0]=='-'){ friendA=friendOfGirl[u]; friendB=friendOfGirl[v]; }else{ friendA=friendOfBoy[u]; friendB=friendOfBoy[v]; } }else if(a[0]=='-'){ friendA=friendOfGirl[u]; friendB=friendOfBoy[v]; }else{ friendA=friendOfBoy[u]; friendB=friendOfGirl[v]; } for(auto p:friendA){ for(auto q:friendB){ if(p==v || q==u) continue; if(mp[p][q]) ans.push_back(pair<int,int>(p,q)); } } printf("%d\n",ans.size()); for(auto it:ans) printf("%04d %04d\n",it.first,it.second); } return 0; }