「1139」First Contact

这篇博客讨论了早期年代表达爱情的微妙方式,男孩通过中间人向女孩传递心意。文章介绍了一个算法问题,要求找出两个人之间所有可能的朋友路径以帮助他们建立联系。输入包括友谊关系网络和查询,输出是可能的帮忙朋友对。博主分享了实现思路,包括使用set存储同性朋友和map记录朋友关系,并展示了如何避免潜在的陷阱。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Unlike in nowadays, the way that boys and girls expressing their feelings of love was quite subtle in the early years. When a boy A had a crush on a girl B, he would usually not contact her directly in the first place. Instead, he might ask another boy C, one of his close friends, to ask another girl D, who was a friend of both B and C, to send a message to B – quite a long shot, isn’t it? Girls would do analogously.

Here given a network of friendship relations, you are supposed to help a boy or a girl to list all their friends who can possibly help them making the first contact.

Input Specification:

Each input file contains one test case. For each case, the first line gives two positive integers N (1 < N ≤ 300) and M, being the total number of people and the number of friendship relations, respectively. Then M lines follow, each gives a pair of friends. Here a person is represented by a 4-digit ID. To tell their genders, we use a negative sign to represent girls.

After the relations, a positive integer K (≤ 100) is given, which is the number of queries. Then K lines of queries follow, each gives a pair of lovers, separated by a space. It is assumed that the first one is having a crush on the second one.

Output Specification:

For each query, first print in a line the number of different pairs of friends they can find to help them, then in each line print the IDs of a pair of friends.

If the lovers A and B are of opposite genders, you must first print the friend of A who is of the same gender of A, then the friend of B, who is of the same gender of B. If they are of the same gender, then both friends must be in the same gender as theirs. It is guaranteed that each person has only one gender.

The friends must be printed in non-decreasing order of the first IDs, and for the same first ones, in increasing order of the seconds ones.

Sample Input:

10 18
-2001 1001
-2002 -2001
1004 1001
-2004 -2001
-2003 1005
1005 -2001
1001 -2003
1002 1001
1002 -2004
-2004 1001
1003 -2002
-2003 1003
1004 -2002
-2001 -2003
1001 1003
1003 -2001
1002 -2001
-2002 -2003
5
1001 -2001
-2003 1001
1005 -2001
-2002 -2004
1111 -2003

Sample Output:

4
1002 2004
1003 2002
1003 2003
1004 2002
4
2001 1002
2001 1003
2002 1003
2002 1004
0
1
2003 2001
0

Ω

又是单身狗无法理解的一道题目,我由衷地希望,大家能够直球地面对自己的心上人,真诚才是必杀技,谢谢。

累了,简单的外表下,藏着一颗月球的心,不要问我在哪,有坑的地方就有我……. 什么叫做一步一个脚印,就是每当你提交前觉得要ac的时候,结果只多红了一个测试点,甚至毫无变化。

A喜欢B,怂的1b,希望通过好基友C找到B的好闺蜜D去试探B(你这种人能脱单才怪哦)⚠️AC,BD必须同性别。想法非常简单,用set存储每个人的同性朋友,然后用一个map<int,bool> r 所有朋友对,来表示之间是否为朋友。那么我们就直接枚举A和B的所有同性朋友,然后用r来判断是否为朋友。由于set会自动按照编号升序排序,因此按依次遍历得到的结果顺序即为题意要求。

思路就是这么简单,接下来是环形坑枚举阶段:

  1. 四位编号输入可能存在“0000”和“-0000”,如果是用int读取就无法区分性别,因此需要用字符串读取后判断长度得出性别

  2. A和B可能本身就是同性朋友(为这道题的格局点赞),因此枚举A的同性朋友时需要跳过B

  3. 同样的,枚举B的同性朋友时跳过A(很重要,有时候想到2也不见得会记得3)

  4. C和D不能是同一个人,但你只要有判断C和D是否是朋友就不需要关注这点

  5. 如果是以int存储编号的,最后输出别忘记格式化%04d

这还不是最开心的,最让人激动的是唯一的测试样例没有出现上面的任何一个坑: ) 可谓埋的一手好雷。外加这种题目不好自己构造测试样例,有时只能站在出题人的角度去找洞攻击自己代码。道高一尺,魔高一丈,只是未曾想过路途如此险恶。


🐎

#include <iostream>
#include <set>
#include <vector>
#include <map>

using namespace std;

int main()
{
    int n, m, a, b;
    scanf("%d %d", &n, &m);
    map<int, set<int>> f;
    map<int, bool> r;
    string sa, sb;
    for (int i = 0; i < m; ++i)
    {
        cin >> sa >> sb;
        a = stoi(sa), b = stoi(sb);
        if (sa.size() == sb.size())
            f[abs(a)].insert(abs(b)), f[abs(b)].insert(abs(a));
        r[abs(a) * 10000 + abs(b)] = r[abs(b) * 10000 + abs(a)] = true;
    }
    scanf("%d", &m);
    for (int i = 0; i < m; ++i)
    {
        vector<int> ans;
        scanf("%d %d", &a, &b);
        a = abs(a), b = abs(b);
        for (auto &u: f[a])
        {
            if (u == b) continue;
            for (auto &v: f[b])
            {
                if (v == a) continue;
                if (r[u * 10000 + v])
                    ans.push_back(u * 10000 + v);
            }
        }
        printf("%zu\n", ans.size());
        for (auto &t: ans)
            printf("%04d %04d\n", t / 10000, t % 10000);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值