A1139
题目链接
个人思路
- 由于数据量是1w,如果用邻接表邻接矩阵存储总觉得会超限
- 声明两个结构体,person存储每个人的id,性别,vector存储朋友id,便于遍历;Helper存储两个中间人的id
- 输入数据,初始化每个人的变量
- 输入一对情侣A喜欢B,在第一个人A的朋友中寻找同性朋友C,在C的朋友中寻找与B同性的朋友D,在D的朋友中如果能找到B,将C,D存入ans中,遍历结束输出答案即可
注意:
- 依照题意,是存在AB同性的情况的哈哈哈,所以if条件为A同性,B同性来寻找C,D,而不能明确说明D一定与A异性
- 明确要找的是中间人:在筛选每个人朋友中,要注意不能在A的朋友中直接找到B,不能在C的朋友中直接找到A和B
- 注意由于-0000与+0000在int中都是0,无法判断性别,因此最开始要用字符串读入来判断性别
- 柳神使用10000 * p1 + p2的哈希函数,也是值得学习的!用hash替代二维4位数数组是个好方法
个人思路代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10010;
int N, M, K;
struct Person{
int id;
int gender = 1;
vector<int> mate;
}people[maxn];
struct Helper{
int firid;
int secid;
Helper(){}
Helper(int fid, int sid)
{
firid = fid;
secid = sid;
}
};
vector<Helper> ans;
unordered_map<int ,bool> gendermp;
void findFriend(int A, int B)
{
for(int i = 0; i < people[A].mate.size(); ++i)
{
int pid = people[A].mate[i];
if(people[pid].gender == people[A].gender && pid != B)
{
for(int j = 0; j < people[pid].mate.size(); ++j)
{
int qid = people[pid].mate[j];
if(people[qid].gender == people[B].gender && qid != B && qid != A)
{
for(int k = 0; k < people[qid].mate.size(); ++k)
{
int rid = people[qid].mate[k];
if(people[rid].id == B)
{
ans.push_back(Helper(pid, qid));
}
}
}
}
}
}
}
bool cmp(Helper h1, Helper h2)
{
if(h1.firid != h2.firid)
return h1.firid < h2.firid;
else
return h1.secid < h2.secid;
}
int main(int argc, char *argv[]) {
scanf("%d%d", &N, &M);
for(int i = 0; i < M; ++i)
{
char s1[10], s2[10];
scanf(" %s %s", s1, s2);
int p1, p2;
sscanf(s1, "%d", &p1);
sscanf(s2, "%d", &p2);
if(s1[0] == '-')
{
p1 *= -1;
people[p1].gender = 0;
}
if(s2[0] == '-')
{
p2 *= -1;
people[p2].gender = 0;
}
people[p1].id = p1;
people[p1].mate.push_back(p2);
people[p2].id = p2;
people[p2].mate.push_back(p1);
}
scanf("%d", &K);
while(K--)
{
int A, B;
ans.clear();
scanf("%d%d", &A, &B);
A = abs(A);
B = abs(B);
findFriend(A, B);
printf("%d\n", ans.size());
sort(ans.begin(), ans.end(), cmp);
for(int i = 0; i < ans.size(); ++i)
{
Helper h = ans[i];
printf("%04d %04d\n", h.firid, h.secid);
}
}
return 0;
}