PAT 1034. Head of a Gang

本文介绍了一种使用C++解决帮派成员间通话记录分析的问题,通过DFS遍历来找出符合特定条件的帮派首领及其帮派规模。文章详细展示了如何利用map和vector等数据结构,并结合字符串处理技巧来完成任务。

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

用C++写了比较长的时间,仍然出现一个段错误,网上说是“名字太长” 1034. Head of a Gang (30)


我的思路是:保存一个名字字符串到int的map2int,保存所有的名字persons,每个名字打的时间cnt[],两个人是否通话过contact[1002][1002],每次遍历完一个联通分量的所有人vector <string> gangs,最终的结果vector <string> rst。


也是比较中规中矩的解法,说什么就做什么,读取完数据后,DFS遍历联通分量,结果保存到vector,在sort后输出即可


有些知识:

(1)C++的map实现value值的修改

std::map<int, string>::iterator it;
it = mymap.find(key);
if(it == mymap.end())
<span style="white-space:pre">	</span>mymap.insert(std::make_pair(key, value));
else
 {
  <span style="white-space:pre">	</span>it->second = value;
 }
(2)实现string + int = string

    int a = 2;
    string b = "abc";
    stringstream ss;
    ss << a << b;
    cout << ss.str() << endl;

(3)对vector rst进行排序

sort(rst.begin(), rst.end());
(4)string是对象,string.c_str()是字符串,scanf时%s需要的是字符串参数, string对象要用cin





#include <cstdio>
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>

using namespace std;

int calls, threshold;
vector <string> persons;
map <string, int> map2int;
int cnt[1002];
bool contact[1002][1002];
vector <string> gangs;
vector <string> rst;
bool marked[1002];

void judgeForJustic() {
    int sum = 0, max = 0;
    string boss;
    for(int i=0; i<gangs.size(); i++) {
        sum += cnt[map2int[gangs[i]]];
        if(cnt[map2int[gangs[i]]] > max) {
            boss = gangs[i];
            max = cnt[map2int[gangs[i]]];
        }
    }
    if(sum > threshold * 2 && gangs.size() > 2) {
        //cout << sum << endl;
        stringstream ss;
        ss << gangs.size();
        rst.push_back(boss + " " + ss.str());
    }
}

void dfs(int start) {
    for(int i=1; i<persons.size(); i++) {
        if(!marked[i] && contact[start][i]) {
            gangs.push_back(persons[i]);
            marked[i] = true;
            dfs(i);
        }
    }
}

void dfs() {
    //marked[map2int[persons[0]]] = true;
    for(int i=0; i<persons.size(); i++) {
        if(!marked[map2int[persons[i]]]) {
            gangs.clear();
            gangs.push_back(persons[i]);
            marked[i] = true;
            dfs(i);

            judgeForJustic();
        }
    }
}



int main()
{
    scanf("%d %d", &calls, &threshold);

    string name1, name2;
    int time, pos = 0;

    for(int i=0; i<calls; i++) {
        cin >> name1 >> name2 >> time;

        std::map<string, int>::iterator it;
        it = map2int.find(name1);
        if(it == map2int.end()) {
            map2int.insert(map<string, int>::value_type(name1, pos++));
            persons.push_back(name1);
        }
        it = map2int.find(name2);
        if(it == map2int.end()) {
            map2int.insert(map<string, int>::value_type(name2, pos++));
            persons.push_back(name2);
        }
        cnt[map2int.find(name1)->second] += time;
        cnt[map2int.find(name2)->second] += time;
        contact[map2int.find(name1)->second][map2int.find(name2)->second] = true;
        contact[map2int.find(name2)->second][map2int.find(name1)->second] = true;
    }

    dfs();

    printf("%d\n", rst.size());
    sort(rst.begin(), rst.end());
    for(int i=0; i<rst.size(); i++) {
        printf("%s\n", rst[i].c_str());
    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值