算法学习(STL专题)

文章包含多道编程题目,主要涉及使用map数据结构和优先队列(priority_queue)解决上网统计、求有序表最小和以及模拟新闻系统发送新闻的问题。此外,还有一道关于考试座位号查询的题目,利用map存储考生信息。
摘要由CSDN通过智能技术生成

F (6). 上网统计(map<string,vector<string> >)


时间限制: 1000MS

空间限制: 256MB

题目描述

在一个网络系统中有 N 个用户、M 次上网记录。每个用户可以自己注册一个用户名,每个用户名是一个只含小写字母且长度小于 1000 的字符串。每个上网的账号每次上网都会浏览网页,网页名是以一个只含小写字母且长度小于 1000 的字符串,每次上网日志里都会有记录,现在请统计每个用户每次浏览了多少个网页。

输入描述

第 1 行包含两个用 1 个空格隔开的正整数 N(1≤N≤1000)和 M(1≤M≤5000)。

第 2∼M+1 行,每行包含 2 个用 1 个空格隔开的字符串,分别表示用户名和浏览的网页名。

输出描述

共 N行,每行的第一个字符串是用户名,接下来的若干字符串是这个用户依次浏览的网页名(之间用一个空格隔开)。按照用户名出现的次序排序输出。 

样例

输入 

5 7 
goodstudyer bookshopa 
likespacea spaceweb
goodstudyer bookshopb 
likespaceb spaceweb 
likespacec spaceweb
likespacea juiceshop
gameplayer gameweb

输出 

goodstudyer bookshopa bookshopb 
likespacea spaceweb juiceshop
likespaceb spaceweb
likespacec spaceweb 
gameplayer gameweb 
#include<bits/stdc++.h>
using namespace std;

int n,m,cnt;
string s,t;
map<int,string> st;//记录用户注册顺序
map<string,vector<string> > mp;//first存用户,second存上网记录

int main() {
	cin>>n>>m;
	while(m--) {
		cin>>s>>t;
		if(mp[s].empty())//当用户第一次出现时,记录位置
			st[cnt++]=s;
		mp[s].push_back(t);//存入上网记录
	}
	for(int i=0; i<cnt; i++) {
		cout<<st[i];
		for(int j=0; j<mp[st[i]].size(); j++)
			cout<<" "<<mp[st[i]][j];//输出对应用户全部上网记录
		cout<<"\n";
	}
	return 0;
}

S (19). 有序表的最小和(priority_queue)


时间限制: 1000MS

空间限制: 64MB

题目描述

给出两个长度为n的有序表A和B,在A和B中各任取一个元素,可以得到n^2个和,求这些和中最小的n个

输入描述

第一行包含一个整数n(n≤400000)

第二行与第三行分别有n个整数,分别代表有序表A和B,整数之间由一个空格隔开,大小在长整数范围之内,保证有序表的数据单调递增。

输出描述

输出共n行,每行一个整数,第i行为第i小的和,数据保证在长整数范围之内

样例

输入

3
1 2 5
2 4 7

输出

3
4
5
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=4e5+10;

priority_queue<int > q;//存数
int n,a[N],b[N],cnt;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);

	cin>>n;
	for(int i=0; i<n; i++)
		cin>>a[i];
	for(int i=0; i<n; i++)
		cin>>b[i];
	for(int i=0; i<n; i++)
		q.push(a[0]+b[i]);//填入优先队列中n个数
	for(int i=1; i<n; i++)
		for(int j=0; j<n; j++) {
			int t=a[i]+b[j];
			if(t>q.top()) break;//递推更新队列
			q.pop();
			q.push(t);
		}
	while(!q.empty()) {
		a[cnt++]=q.top();
		q.pop();
	}//逆序存储输出
	for(int i=n-1; i>=0; i--)
		cout<<a[i]<<"\n";
	return 0;
}

T (20). 桐桐的新闻系统(priority_queue+pair)


时间限制: 1000MS

空间限制: 256MB

题目描述

桐桐为期末的计算机作业设计了一套新闻系统,他把这套系统称为 Argus。

使用这套系统的用户可以向这套系统注册,然后这套系统就会以用户要求发送新闻的时间间隔向用户发送一次新闻。

向 Argus注册的指令具有以下格式:

Register  Q_num  Period

Q_num(0<Q_num<3000) 是用户的 ID,Period (0<Period3000) 是间隔。注册后 Period 秒,结果会第一次到达。

所有的用户都有不同的Q_num。桐桐测试了一段时间后,想知道系统前 K 次给谁发送新闻了。如果同一时间发送多个新闻,以 Q _ num 的升序排列。

输入描述

第一部分是注册指令,每条一行。指令数不超过1000,所有指令同时执行完。此部分以“#”结束。

第二部分仅一行一个正数 K , K≤10000。

输出描述

输出前 K个新闻发送到的用户的 Q _ num ,每行一个。

样例

输入

Register 2004 200
Register 2005 300
#
5

输出 

2004
2005
2004
2004
2005
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
#define fi first
#define se second
const int N=1e3+10;

priority_queue<PII,vector<PII>,greater<PII> > qe;//first指示时间延迟,second指示用户名
int q[N],p[N];
int n,cnt;
char s[15];

int main() {
	while(cin>>s) {
		if(s[0]=='#')
			break;
		cin>>q[cnt]>>p[cnt];
		cnt++;
	}
	cin>>n;
	for(int j=0; j<cnt; j++)
		for(int i=1; i<=n; i++)
			qe.push(make_pair(p[j]*i,q[j]));
            //填入队列升序排列时间延迟,若延迟相等升序排列用户
	while(n--) {
		cout<<qe.top().se<<"\n";
		qe.pop();
	}
	return 0;
}

L1-005 考试座位号(map<int,pair<long long,int> >)


每个 PAT 考生在参加考试时都会被分配两个座位号,一个是试机座位,一个是考试座位。正常情况下,考生在入场时先得到试机座位号码,入座进入试机状态后,系统会显示该考生的考试座位号码,考试时考生需要换到考试座位就座。但有些考生迟到了,试机已经结束,他们只能拿着领到的试机座位号码求助于你,从后台查出他们的考试座位号码。

输入格式:

输入第一行给出一个正整数 N(≤1000),随后 N 行,每行给出一个考生的信息:准考证号 试机座位号 考试座位号。其中准考证号由 16 位数字组成,座位从 1 到 N 编号。输入保证每个人的准考证号都不同,并且任何时候都不会把两个人分配到同一个座位上。

考生信息之后,给出一个正整数 M(≤N),随后一行中给出 M 个待查询的试机座位号码,以空格分隔。

输出格式:

对应每个需要查询的试机座位号码,在一行中输出对应考生的准考证号和考试座位号码,中间用 1 个空格分隔。

输入样例:

4
3310120150912233 2 4
3310120150912119 4 1
3310120150912126 1 3
3310120150912002 3 2
2
3 4

输出样例:

3310120150912002 2
3310120150912119 1

代码长度限制

16 KB

时间限制

200 ms

内存限制

64 MB

#include<bits/stdc++.h>
using namespace std;

int n,x,y;
long long t;
map<int,pair<long long,int> > mp;

int main() {
	cin>>n;
	while(n--) {
		cin>>t>>x>>y;
		mp[x]=make_pair(t,y);
	}
	cin>>n;
	while(n--) {
		cin>>x;
		printf("%lld %d\n",mp[x].first,mp[x].second);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

panjyash

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值