POJ 3297 Open Source STL(map+set+pair)

为了熟悉STL,这道题用到的东东还挺多的,存档~
感谢小灰灰的好东西,囊括了许多STL的基本用法。

原题见POJ 3297

大写的是项目名,小写的是参与此项目的人名,两者一对多。所以想到了用map<string, set<> >来存。
如果有在多个项目下留名的,则此人无效;若一人在一项目下重复留名,只记一次。人和编号对应起来,用map<string, int>存,另开一个数组,给一个人留的项目计数,之后备用。同时确定了上面那个map里set的类型map<string, set<int> >
将项目以及人数存在pair<int, second>下,答案放在vector<pair<int, string> >下,按照first递减,second递增的方式输出。需要构造比较函数cmp,在sort里引用。
sort默认按照first、second为第一、二关键字排序输出。如果加个greater<type>()则逆序输出。本题要重写。

PS:不能用auto!打类型好烦…

附代码

/*--------------------------------------------
 * File Name: POJ 3297
 * Author: Danliwoo
 * Mail: Danliwoo@outlook.com
 * Created Time: 2016-05-25 00:48:25
--------------------------------------------*/

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#define N 10010
using namespace std;
map <string, int> stu;
map <string, set<int> > pro;
vector< pair <int, string> >ans;
int a[N], n, m;
string str, book;
void init(){
    stu.clear();
    book.clear();
    pro.clear();
    ans.clear();
    n = m = 0;
    memset(a, 0, sizeof(a));
}
bool cmp(const pair<int, string> &lhs, const pair<int, string> &rhs)
{
    if(rhs.first == lhs.first) return lhs.second < rhs.second;
    return lhs.first > rhs.first;
}
void solve(){
    std::map<string, set<int> >::iterator it;
    std::set<int>::iterator q;
    for(it = pro.begin(); it != pro.end();it++){
        int cnt = 0;
        for(q = it->second.begin(); q != it->second.end();q++)
            if(a[*q] == 1) cnt++;
        ans.push_back(make_pair(cnt, it->first));
    }
    sort(ans.begin(), ans.end(), cmp);
    // sort(ans.begin(), ans.end(), greater<pair <int, string> >());
    vector< pair <int, string> >::iterator ak;
    for(ak = ans.begin();ak != ans.end();ak++)
        cout << ak->second << " " << ak->first << endl;
}
int main()
{
    init();
    while(getline(cin, str)){
        if(str == "0") break;
        if(str == "1") {
            solve();
            init();
            continue;
        }
        if(str[0] >= 'A' && str[0] <= 'Z'){
            book = str;
            pro[book].insert(-1);
        }
        else{
            map <string, int >::iterator iter = stu.find(str);
            if(iter == stu.end())
                stu[str] = m++;
            std::set<int>::iterator q = pro[book].find(stu[str]);
            if(q == pro[book].end()){
                a[stu[str]]++;
                pro[book].insert(stu[str]);
            }
        }
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值