华为机试-朋友圈个数C++解法

给定一组朋友关系,统计一下该朋友关系网中的朋友圈个数。

朋友圈的定义:一个朋友圈至少由3个朋友组成,且要求同一个朋友圈中的任意两个人都具有直接的朋友关系。
输入描述
输入一个朋友关系列表,如 Fiends =A.B],[A.C],IB,DI,其中的每一个元素 Friendsi表示 Friends[i][0)和 Friends [i][1] 是朋友关系 先输入一个数字 N 代表关系的总数,后面每条关系一行,两个成员以逗号分隔
输出描述
输出一个整数,表示整个关系网中朋友圈的个数
补充
1:Friends.length>=1,Friends.length<= 10^3
2:输入的总朋友个数<= 100
3:输入保证 Friend[i][0]和 Friend[i][1]一定不一样,且同一关系不会反向输入,即不会同时输入[A,B] 和 [B,A]。

4:不考虑子朋友圈,即当发现 [A,B,C,D]组成一个朋友圈时,[A,B,C]、[A,B,D]等子朋友圈不单独计数

示例1:

输入:

3
A,B
A,C
B,D

输出:

0

示例2:

输入:

7
A,B
A,C
B,C
A,D
D,E
B,D
A,E


输出:

3

示例3:

输入:

6
A,B
A,C
B,C
A,D
B,D
D,C

输出:

1
————————————————
版权声明:本文为CSDN博主「MISAYAONE」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/misayaaaaa/article/details/155455278

//bronKerbosch算法是最优解,但是对于现在的我来说好难啊!如果考试考到了还是老老实实邻接矩阵+暴力算法吧,起码简单一些的用例应该是能通过的
#牛客AI配图神器#
#include <iostream>
#include <unordered_map>
#include <string>
#include <cmath>
#include <algorithm>
#include <bitset>
using namespace std;

//定义全局变量
bool isFriend[100][100] = { false };//记录谁和谁是朋友
int totalPeople;
vector<int> maxCircle;

//P-还可以考虑加入到朋友圈的人
//X-已经排除,不考虑的人
void bronKerbosch(int R, int P, int X) {
if (P == 0 && X == 0) {
if (std::bitset<32>(R).count() >= 3) {
maxCircle.push_back(R);
}
return;
}
int pivot = 0;//枢顶点ID
if (P != 0) {
//找到P中第一个人的id
for (int i = 0; i < totalPeople; i++) {
if (P & (1 << i)) {
pivot = i;
break;
}
}
}
//遍历P中所有不是枢轴朋友的人
for (int v = 0; v < totalPeople; v++) {
//检查P的第v位是否为1
if (P & (1 << v)) {
//if (!isFriend[pivot][v]) continue;
int newR = R | (1 << v);
int newP = 0;
for (int u = 0; u < totalPeople; u++) {
if ((P & (1 << u)) && isFriend[v][u]) {
newP |= (1 << u);
}
}
//计算新的X
int newX = 0;
for (int u = 0; u < totalPeople; u++) {
if ((X & (1 << u)) && isFriend[v][u]) {
newX |= (1 << u);
}
}
//递归
bronKerbosch(newR, newP, newX);
P &= ~(1 << v);
X |= (1 << v);
}
}
}

int main() {
////声明变量名
intN;
cin >> N;
cin.ignore();

if (N <= 0) {
cout << 0 << endl;
return 0;
}

//把人名转换为数字编号
unordered_map<string, int> idMap;
vector<string> names;
int nextId = 0;

//读取所有朋友关系
for (int i = 0; i < N; i++) {
string line;
getline(cin, line);  // 读取整行

// 处理可能的空格
size_t commaPos = line.find(',');
if (commaPos == string::npos) {
// 没有逗号,格式错误
continue;
}

string a = line.substr(0, commaPos);
string b = line.substr(commaPos + 1);

// 去除首尾空格
a.erase(0, a.find_first_not_of(" \t"));
a.erase(a.find_last_not_of(" \t") + 1);
b.erase(0, b.find_first_not_of(" \t"));
b.erase(b.find_last_not_of(" \t") + 1);

// 给人分配id
if (!idMap.count(a)) {
idMap[a] = nextId++;
}
if (!idMap.count(b)) {
idMap[b] = nextId++;
}
int idA = idMap[a];
int idB = idMap[b];
//标记他们是朋友
isFriend[idA][idB] = true;
isFriend[idB][idA] = true;
}
totalPeople = nextId;

if (totalPeople < 3) {
cout << 0 << endl;
return 0;
}

int P = 0;
for (int i = 0; i < totalPeople; i++) {
P |= (1 << i);//把第i位设为1
}

maxCircle.clear();

bronKerbosch(0, P, 0);

sort(maxCircle.begin(), maxCircle.end(), [](int a, int b) {
return std::bitset<32>(a).count() > std::bitset<32>(b).count();
});
//存储真正独立的朋友圈
vector<int> uniCircle;
for (int Circle : maxCircle) {
bool isSubset = false;
for (int larger : uniCircle) {
if ((Circle & larger) == Circle) {
isSubset = true;
break;
}
}
if (!isSubset) {
uniCircle.push_back(Circle);
}
}
cout << uniCircle.size() << endl;
}
全部评论

相关推荐

11-25 11:18
已编辑
华中师范大学 Unity3D客户端
因为我是一个月前投的简历,但是等了一周没等到约面以为不会有机会了就没准备,结果过了一个月突然打电话约面。本人第一次面试,没准备过面经也没刷算法题(力扣十道题的实力)算是完全没实力的面试。面试得也是一团糟,好多问题答不上来,大概率过几天就会挂了。本人不太会c++,虽然CS也没好到哪里去11.24&nbsp;一面自我介绍问了一下项目,因为简历上只有项目。问了一下项目是跟着教程做的还是自己做的。问了一下项目里的BUFF系统。听到buff分配是switch语句后就没深入了,估计是觉得写的不行。问八股讲一下c++里的多态多态里的虚函数的底层是怎么实现的?(回答了虚函数表,但是太紧张了,说的乱七八糟的)假如有十个同一个类的对象,虚函数表有几份(答一份)虚函数表存储在内存中的哪个区域?(答在rodata区域)c++中的内存分区是怎么样的?(静态存储区、rodata区,剩下的想不起来了,就给面试官说我的c++不太好,面试官就不再追问了,开始问c#了)c#的堆和栈?(说了一些乱七八糟的东西,扯到了堆是由GC控制的,肯定没答对)你对c#的委托理解?(说了一点委托和多播委托,以及存储关系,他们怎么存储函数)委托怎么删除某个方法(答使用-=运算符,不确定对不对)链表与数组的区别(回答了存储空间分配,插入删除的区别)数组插入的时间复杂度(答O(n))哈希表的理解?(我回答了字典处理哈希表的逻辑,顺便提到了哈希冲突)哈希冲突怎么解决?(字典里采用了链地址法,大概讲了一下,但是语言非常混乱,实在是太紧张了)了不了解平衡二叉树的概念?(这时候以及蒙了,一年前学的数据结构,猛地没想起来,随口答了一下模糊概念)平衡二叉树的左右子树深度差值是多少(答0或1)手撕平衡二叉树的判断,要求自己构建树结构(原本以为没手撕的,结果还是来了,因为忘了平衡二叉树的概念,写了40分钟没写出来,深度判断用的还是层次遍历)讲一下代码思路(一边讲面试官一边看,估计看到代码错了,没深入问)问渲染管线(答,cpu将数据传入到GPU,然后经过顶点着色器、片元着色器等处理,然后投影、裁剪、最后进入光栅化整合输出)深度测试是在什么阶段实现的?(答光栅化,这里答错了应该,下来后搜了发现是在片元着色器阶段)如果要实现半透明的话shader代码怎么写?(不会,直接说了不知道,只了解shader&nbsp;graph知识,现在想想应该可以在深度检测时对后方物体进行颜色均值处理?不太确定)反问环节问我现在基本都是在做项目,这一阵子发现自己开发项目与面试经验不是特别吻合,如果接下来要找面试的话应该往哪个方向走。面试官说我不会c++的话在面试的时候会有一定劣势,如果要做项目的话还是争取能做到把游戏完整上架的程度才比较好,项目算是加分项。相比之下把基础弄好会好一些。然后又聊了很多有关c++和c#的事情,说基础知识之所以是c++是因为c++更偏向于底层,在回答的时候可以描述的更清晰一点。(如果需要的话可以单独开一篇文章说,面试官还是讲了很多内容的)问是哪一个项目组的?游戏还在研发阶段。整体面试下来刚开始的时候非常紧张,语言组织不太好。不过面试官人很好,很有耐心,第一次面试还没准备答成这样子也是没啥可说的,接下来就坐等被挂了。11.25&nbsp;挂
查看22道真题和解析
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务