POJ 3297 Open Source STL

15 篇文章 0 订阅

题目意思:
有很多个项目(大写字母表示), 每个项目有很多学生报名,但是有效的报名是有规矩的。
如果有在多个项目下留名的,则此人无效;若一人在一项目下重复留名,只记一次。
题目最后要求输出,每个项目的项目名,以及有效的学生报名的人数。

本题要点:
1、这里,就是用map 暴力计算筛除 在多个项目报名的学生
2、最后输出结果,先按项目报名的学生人数从高到低,(如果相同)则按项目的字典序输出

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <string>
using namespace std;
const int MaxN = 110;
map<string, set<string> > g_map;	// 项目名字对应于 所有的学生名字
map<string, int> g_stu;				// 每个学生的报名 的 项目个数

struct Pro
{
	string p;
	int stu_num;
}projects[MaxN];

bool cmp(const Pro& a,  const Pro& b)
{
	if(a.stu_num != b.stu_num)
	{
		return a.stu_num > b.stu_num;
	}
	return a.p < b.p;
}

int main()
{
	string line, project, stu;
	while(getline(cin, line) && line != "0")
	{
		if(line == "1")
		{
			set<string>::iterator it = g_map[project].begin();	
			while(it != g_map[project].end())
			{
				g_stu[*it]++;	
				++it;
			}
			map<string, int>::iterator it2 = g_stu.begin();
			while(it2 != g_stu.end())
			{
				if(it2->second == 1) //所有只报名一个项目的学生名次删除	
				{
					g_stu.erase(it2++);
				}else{
					++it2;
				}
			}
			map<string, set<string> >::iterator it3 = g_map.begin();
			while(it3 != g_map.end())
			{
				set<string>::iterator it4 = it3->second.begin();
				while(it4 != it3->second.end())	
				{
					if(g_stu.find(*it4) != g_stu.end())	// 如果这个项目有的学生报名多个项目,则删除该学生的信息
					{
						it3->second.erase(it4++);
					}else{
						++it4;	
					}
				}
				++it3;
			}
			int cnt = 0;
			it3 = g_map.begin();
			while(it3 != g_map.end())
			{
				projects[cnt].p = it3->first;
				projects[cnt++].stu_num = it3->second.size();
				++it3;
			}
			sort(projects, projects + cnt, cmp);
			for(int i = 0; i < cnt; ++i)
			{
				printf("%s %d\n", projects[i].p.c_str(), projects[i].stu_num);
			}
			g_map.clear();
			g_stu.clear();
			continue;
		}
		if(line[0] >= 'a' && line[0] <= 'z')
		{
			stu = line;
			g_map[project].insert(stu);	
		}else{
			if(g_map.size()> 0)//计算前一个项目组的信息
			{
				set<string>::iterator it = g_map[project].begin();	
				while(it != g_map[project].end())
				{
					g_stu[*it]++;	
					++it;
				}
			}
			project = line;
		}
	}
	return 0;
}

/*
UBQTS TXT
tthumb
LIVESPACE BLOGJAM
philton
aeinstein
YOUBOOK
j97lee
sswxyzy
j97lee
aeinstein
SKINUX
1
0
*/

/*
YOUBOOK 2
LIVESPACE BLOGJAM 1
UBQTS TXT 1
SKINUX 0
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值