【GPLT 二阶题目集】L2-028 秀恩爱分得快

本文介绍了一个趣味社交算法问题“秀恩爱分得快”,通过分析情侣与他人共同出现的照片数量来评估亲密程度。算法实现了情侣间及与其他异性好友间亲密度的计算,并确定是否存在比对方更亲密的朋友。

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

古人云:秀恩爱,分得快。

互联网上每天都有大量人发布大量照片,我们通过分析这些照片,可以分析人与人之间的亲密度。如果一张照片上出现了 K 个人,这些人两两间的亲密度就被定义为 1/K。任意两个人如果同时出现在若干张照片里,他们之间的亲密度就是所有这些同框照片对应的亲密度之和。下面给定一批照片,请你分析一对给定的情侣,看看他们分别有没有亲密度更高的异性朋友?

输入格式:

输入在第一行给出 2 个正整数:N(不超过1000,为总人数——简单起见,我们把所有人从 0 到 N-1 编号。为了区分性别,我们用编号前的负号表示女性)和 M(不超过1000,为照片总数)。随后 M 行,每行给出一张照片的信息,格式如下:

K P[1] ... P[K]

其中 K(≤ 500)是该照片中出现的人数,P[1] ~ P[K] 就是这些人的编号。最后一行给出一对异性情侣的编号 A 和 B。同行数字以空格分隔。题目保证每个人只有一个性别,并且不会在同一张照片里出现多次。

输出格式:

首先输出 A PA,其中 PA 是与 A 最亲密的异性。如果 PA 不唯一,则按他们编号的绝对值递增输出;然后类似地输出 B PB。但如果 A 和 B 正是彼此亲密度最高的一对,则只输出他们的编号,无论是否还有其他人并列。

输入样例1:

10 4
4 -1 2 -3 4
4 2 -3 -5 -6
3 2 4 -5
3 -6 0 2
-3 2

输出样例1:

-3 2
2 -5
2 -6

输入样例2:

4 4
4 -1 2 -3 0
2 0 -3
2 2 -3
2 -1 2 
-3 2

输出样例2:

-3 2

#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;

//需要考虑-0和0是两个性别不同的人,否则测试点2、5、6答案错误
bool cmp(pair<string, double> a, pair<string, double> b)
{
    if (a.second == b.second)
        return abs(atoi(a.first.c_str())) < abs(atoi(b.first.c_str())); //string转char *转int
    return a.second > b.second;
}

int main()
{
    int n, m; cin >> n >> m;
    vector< vector<string> > pictureBox; //照片集
    vector<string> picture; //照片

    int k; string temp;
    for (int i = 0; i < m; i++) {
        cin >> k; getchar();
        while (k--) { //创建一张照片
            cin >> temp; getchar();
            picture.push_back(temp);
        }
        pictureBox.push_back(picture); //将照片放入照片集
        picture.clear(); //清空临时照片的内容
    }

    string a, b; cin >> a >> b;
    //A,B的关系列表<编号,亲密度>
    map<string, double> relationA;
    map<string, double> relationB;

    for (int i = 0; i < pictureBox.size(); i++) { //遍历照片
        //判断这张照片里面是否有a
        if (find(pictureBox[i].begin(), pictureBox[i].end(), a) != pictureBox[i].end()) {
            double love = 1.0 / pictureBox[i].size(); //该照片的亲密度
            for (int j = 0; j < pictureBox[i].size(); j++) { //遍历该照片的每一个人
                if (((a[0]=='-'&&pictureBox[i][j][0]!='-') || (a[0] != '-'&& pictureBox[i][j][0] == '-')) && relationA.find(pictureBox[i][j]) == relationA.end()) { //互为异性且关系列表没有该异性
                    pair<string, double> p = make_pair(pictureBox[i][j], love);
                    relationA.insert(p);
                }
                else if ((a[0] == '-' && pictureBox[i][j][0] != '-') || (a[0] != '-' && pictureBox[i][j][0] == '-')) { //互为异性且关系列表有该异性
                    relationA[pictureBox[i][j]] += love;
                }
            }
        }
        //判断这张照片里面是否有b
        if (find(pictureBox[i].begin(), pictureBox[i].end(), b) != pictureBox[i].end()) {
            double love = 1.0 / pictureBox[i].size(); //该照片的亲密度
            for (int j = 0; j < pictureBox[i].size(); j++) { //遍历该照片的每一个人
                if (((b[0] == '-' && pictureBox[i][j][0] != '-') || (b[0] != '-' && pictureBox[i][j][0] == '-')) && relationB.find(pictureBox[i][j]) == relationB.end()) { //互为异性且关系列表没有该异性
                    pair<string, double> p = make_pair(pictureBox[i][j], love);
                    relationB.insert(p);
                }
                else if ((b[0] == '-' && pictureBox[i][j][0] != '-') || (b[0] != '-' && pictureBox[i][j][0] == '-')) { //互为异性且关系列表有该异性
                    relationB[pictureBox[i][j]] += love;
                }
            }
        }
    }

    vector< pair<string, double> > resA(relationA.begin(), relationA.end());
    vector< pair<string, double> > resB(relationB.begin(), relationB.end());
    sort(resA.begin(), resA.end(), cmp); //根据亲密度对关系列表排序
    sort(resB.begin(), resB.end(), cmp);

    if (relationA.find(b) != relationA.end() && relationB.find(a) != relationB.end() && resA[0].second == relationA[b] && resB[0].second == relationB[a])
        cout << a << " " << b << endl; //在双方关系列表里且都是最高亲密度
    else if (resA.size() == 0 && resB.size() == 0)
        cout << a << " " << b << endl; //双方均为在照片中出现过(未考虑则测试点3答案错误)
    else { //其余情况
        for (int i = 0; i < resA.size(); i++) {
            if (resA[i].second == resA[0].second)
                cout << a << " " << resA[i].first << endl;
        }
        for (int i = 0; i < resB.size(); i++) {
            if (resB[i].second == resB[0].second)
                cout << b << " " << resB[i].first << endl;
        }
    }
    return 0;
}

 注意事项:

参考文章:L2-028 秀恩爱分得快(测试点3说明)   作者:三块不一样的石头

万分感谢大佬的文章点醒了我!不然我得一直卡在-0和测试点3这!!!

如有问题,欢迎提出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花辞树dor

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值