问题:一个人要向另一个人表白,如果他们是异性,那么这个人会先找一个同性中间人,这个同性中间人再找另一个表白目标的同性中间人,最后这个中间人找到表白目标。
如果是同性,那么中间就经过两个同性中间人。
思路:模拟
关键:
1.存在0000或-0000这种更加特殊的情况
2.不存在1024和-1024同时存在的情况,即不同考虑重名,一个人的性别是确定的。
3.A在寻找同性朋友时,需要避免找到他想要的伴侣B,所以当当前朋友就是B或者B的同性朋友就是A时舍弃该结果
4.建立同性朋友之间的表很重要。
5.最后,四位数并不代表前面不会有,因此要注意输出格式 %04d
6.用map<int,bool> 就能够表示两点之间的连接关系,值得学习 !
看了柳神的代码理解后自己的复现代码:
#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>
using namespace std;
const int maxn = 10010;
unordered_map<int,bool> con;
vector<int> v[maxn];
int N,M,K;
struct node{
int a,b;
node(int x,int y):a(x),b(y){}
bool operator < (const node x)const{
return a==x.a?b<x.b:a<x.a;
}
};
int main(){
freopen("1.txt","r",stdin);
scanf("%d %d",&N,&M);
string a,b;
for(int i=0;i<M;i++){
cin >> a >> b;
if(a.length()==b.length()){
//长度相等说明是同性朋友
v[abs(stoi(a))].push_back(abs(stoi(b)));
v[abs(stoi(b))].push_back(abs(stoi(a)));
}
//这里十分巧妙,用一个int就表示了两点之间的关系
con[abs(stoi(a))*10000+abs(stoi(b))] = con[abs(stoi(b))*10000+abs(stoi(a))] = true;
}
scanf("%d",&K);
vector<node> ans;
for(int i=0;i<K;i++){
ans.clear();
cin >> a >> b;
for(auto c:v[abs(stoi(a))]){
for(auto d:v[abs(stoi(b))]){
if(c!=abs(stoi(b))&&d!=abs(stoi(a))&&con[c*10000+d])
ans.push_back(node(c,d));
}
}
sort(ans.begin(),ans.end());
cout << ans.size() << endl;
for(int i=0;i<ans.size();i++)
printf("%04d %04d\n",ans[i].a,ans[i].b);
}
}