题目要求:
- A和B:A对B心动,可同性可异性;A和C:同性别、朋友关系;B和D:同性别、朋友关系;C和D:朋友,可同性可异性。
- 给出所有人的关系图(可用二维数组或vector存储,用vector比较省内存),给出A和B,找出所有符合要求的C和D。
- 所有找出的C(i)和D(i)的输出顺序:优先输出小的C,若C相等则优先输出小的D。
- 每个人由一个4位数字表示(唯一),前面有’-‘表示女性。
解题思路:
1.本人选择用int存储每个人的id,但是输入时要用string,因为存在-0000的情况,若用int输入会将其存为0,搞反了性别,所以一开始先输入在string再转为int。负的id取正再加10000(如-1001存储为11001),详见代码。
2.使用二维数组vector fr[n+1] 存储关系网(无向图),由于id是4位数字比较难表示,所以直接输入时每新增一个人(如id为a)就用map存储其在fr中的位置(map[a]=i;fr[i]就表示a,可以存放a的所有朋友)。(这样会有点麻烦但是省内存。。。)
3.之后就是给你A和B,先遍历fr[map[A]]找出A的同性朋友C,如果A和B同性就要多考虑找到C不能是B,AB异性就不需要;每找到一个符合要求的C,再去找符合要求的D(同样D与B同性,如果AB同性还要考虑D不能是A也不能是C),最后判断D是不是C的朋友,是的话就是找到一对C和D。
4.由于答案要按一定顺序输出,所以用结点存C和D,设一个vector ans 来放这些结点,用sort对它们排序,比较简单易写。
细节/坑点
1.-0000情况
2.避免C是B、D是A或C的情况
3.哎呀好像都在上面说了…
AC代码(C++)
#include <bits/stdc++.h>
using namespace std;
#define w 10000
struct node{
int c,d;
};
bool cmp(node a,node b)
{ return a.c!=b.c?a.c<b.c:a.d<b.d; }
int main() {
int n,m,k,a,b,c,d,x=1;
string aa,bb;
scanf("%d %d",&n,&m);
vector<int> fr[n+1];
map<int,int> mp;
while(m--)
{
cin>>aa>>bb;
a= aa[0]=='-'?w+abs(stoi(aa)):abs(stoi(aa));
b= bb[0]=='-'?w+abs(stoi(bb)):abs(stoi(bb));
if(mp[a]==0){ mp[a]=x++; }
if(mp[b]==0){ mp[b]=x++; }
fr[mp[a]].push_back(b);
fr[mp[b]].push_back(a);
}
scanf("%d",&k);
while(k--)
{
cin>>aa>>bb;
a= aa[0]=='-'?w+abs(stoi(aa)):abs(stoi(aa));
b= bb[0]=='-'?w+abs(stoi(bb)):abs(stoi(bb));
vector<node> ans;
int ax=mp[a],bx=mp[b];
bool ist=aa.size()==bb.size()?1:0;
for(int i=0;i<fr[ax].size();i++)
{
c=fr[ax][i];
if(((a>=w&&c>=w)||(a<w&&c<w))&&((ist&&c!=b)||!ist))
{
for(int j=0;j<fr[bx].size();j++)
{
d=fr[bx][j];
if(((b>=w&&d>=w)||(b<w&&d<w))&&((ist&&d!=a&&d!=c)||!ist))
{
int cx=mp[c],l=0;
while(l<fr[cx].size()&&fr[cx][l]!=d)
{ l++; }
if(l<fr[cx].size())
{
node t;
t.c= c>=w?c-w:c; t.d= d>=w?d-w:d;
ans.push_back(t);
}
}
}
}
}
sort(ans.begin(),ans.end(),cmp);
printf("%d\n",ans.size());
for(int i=0;i<ans.size();i++)
{ printf("%04d %04d\n",ans[i].c,ans[i].d); }
}
return 0;
}