古人云:秀恩爱,分得快。
互联网上每天都有大量人发布大量照片,我们通过分析这些照片,可以分析人与人之间的亲密度。如果一张照片上出现了 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这!!!
如有问题,欢迎提出。