STL容器入门

一.优先队列

  • 头文件需求
#include<queue>
using namespace std;
  • 常用格式
priority_queue<int,vector<int>,less<int> > p;        英语四级困难户:priority   优先
priority_queue<int,vector<int>,greater<int> >q;

注意的是:less是从大到小,greater是从小到大。

  • 常用操作
q.size();  /*q中的元素个数*/
q.empty();  /*q如果为空,返回1,反之亦然*/
q.push(x);  /*q的末端插入x*/
q.pop();  /*删除队列队头元素*/
q.top();  /*得到队头元素值,但是不删除*/
q.back();  /*得到队尾元素值,不删除*/
  • 例题

众所周知,思远宝宝是一个聪明的天线宝宝。但是永日至秦对此感到非常不服气,于是提出了挑战,他打算和思远宝宝玩一个简单的数字游戏。在每一轮中永日至秦可以选择写下一个数字,或者询问写下的所有数字中思远宝宝第k大的数字是什么。由于永日至秦写下的数字非常多,你来帮思远应付他吧~
Input 本题有多组输入。在每个测试样例中,第一行包括两个正整数n,k(1=<k<=n<=1000000)。然后会有n行承接。如果永日至秦想写下一个数字,那一行会先输入’I’,然后输入他写的数字。如果永日至亲想问第k大的数字是什么,他会在那一行输入’Q’,然后你需要输出第k大的数字是什么。永日至秦在至少写下k个数字前是不会进行询问的。Output 当进行询问时 输出第k大的数 每个输出占用一行
Sample Input
8 3
I 1
I 2
I 3
Q
I 5
Q
I 4
Q
Sample Output
1
2
3

#include<cstdio>
#include<queue>
#include<iostream>
using namespace std;
int main()
{
	int m, n;
	while (cin >> m >> n)
	{
		priority_queue<int, vector<int>, greater<int> > q;
		while (m--)
		{
			char ch;
			cin >> ch;
			int x;
			if (ch == 'I')
			{
				cin >> x;
				q.push(x);
				if (q.size() > n)
				{
					q.pop();
				}
			}
			else if (ch == 'Q')
			{
				cout << q.top() << endl;
			}
		}
	}
	return 0;
}

优先队列的内载函数
看病要排队这个是地球人都知道的常识。 不过经过细心的0068的观察,他发现了医院里排队还是有讲究的。0068所去的医院有三个医生(汗,这么少)同时看病。而看病的人病情有轻重,所以不能根据简单的先来先服务的原则。所以医院对每种病情规定了10种不同的优先级。级别为10的优先权最高,级别为1的优先权最低。医生在看病时,则会在他的队伍里面选择一个优先权最高的人进行诊治。如果遇到两个优先权一样的病人的话,则选择最早来排队的病人。

现在就请你帮助医院模拟这个看病过程。

Input
输入数据包含多组测试,请处理到文件结束。

每组数据第一行有一个正整数N(0<N<2000)表示发生事件的数目。

接下来有N行分别表示发生的事件。

一共有两种事件:

1:“IN A B”,表示有一个拥有优先级B的病人要求医生A诊治。(0<A<=3,0<B<=10)

2:“OUT A”,表示医生A进行了一次诊治,诊治完毕后,病人出院。(0<A<=3)

Output
对于每个"OUT A"事件,请在一行里面输出被诊治人的编号ID。如果该事件时无病人需要诊治,则输出"EMPTY"。

诊治人的编号ID的定义为:在一组测试中,"IN A B"事件发生第K次时,进来的病人ID即为K。从1开始编号。

Sample Input
7
IN 1 1
IN 1 2
OUT 1
OUT 2
IN 2 1
OUT 2
OUT 1
2
IN 1 1
OUT 1

Sample Output
2
EMPTY
3
1
1

#include<cstdio>
#include<queue>
#include<iostream>
#include<string>
using namespace std;
typedef struct node {
	int x;
	int id;
	bool operator < (const node &n)const {
		if (x != n.x)
			return x < n.x;
		else
			return id > n.id;
	}
}node;
int main()
{
	int m;
	while (cin >> m)
	{
		priority_queue<node> p[4];
		int i = 1;
		node t;
		while (m--)
		{
			string ch;
			cin >> ch;
			int x, y;
			if (ch == "IN")
			{
				cin >> x >> y;
				t.id = i;
				t.x = y;
				i++;
				p[x].push(t);
			}
			else if (ch == "OUT")
			{
				int z;
				cin >> z;
				if (p[z].empty())
				{
					cout << "EMPTY" << endl;
				}
				else
				{
					cout << p[z].top().id << endl;
					p[z].pop();
				}
			}
		}
	}
	return 0;
}

二.栈
操作基本与队列一致,参考上面内容即可。

  • 头文件要求
#include<stack>
using namespace std;
  • 例题
    随着新学期的到来,伊格那丢斯火车站现在非常繁忙。很多学生想坐火车回学校(因为伊格那丢火车站的火车是世界上最快的)。但问题来了,只有一条铁路所有的火车都停在那里。所以所有的火车都是从一边进站,从另一边出站。对于这个问题,如果A列先进入铁路,然后B列在A列离开之前进入铁路,那么A列在B列离开之前不能离开。下图说明了问题所在。现在你的问题是,车站里最多有9列火车,所有的火车都有一个ID(编号从1到N),火车按照O1的顺序进入火车,你的任务是确定火车是否可以按照O2的顺序驶出。Input输入 输入包含几个测试用例。每个测试用例由一个整数、列车数和两个字符串组成,列车的顺序为:o1,列车的顺序为:o2。输入被文件结尾终止。在示例输入中提供更多详细信息。Output产量 输出包含一个字符串“否”。如果不能将O2交换为O1,或者应该输出一个包含“是”的行,然后输出交换顺序的方式(对于进入铁路的列车,应输出“in”,对于出铁路的列车,应输出“out”)。在每个测试用例之后打印一行包含“finish”。示例输出中的更多详细信息。
    Sample Input
    3 123 321
    3 123 312
    Sample Output
    Yes.
    in
    in
    in
    out
    out
    out
    FINISH
    No.
    FINISH
#include<cstdio>
#include<string>
#include<iostream>
#include<stack>
using namespace std;
int main()
{
	string a,b;
	int n,i,j;
	while(cin>>n)
	{
		cin>>a>>b;
		stack<char> s1,s2;
		i=0;
		j=0;
		while(i<a.length())
		{
			s1.push(a[i]);
			while(s1.top()==b[j])
			{
				if(!s1.empty())
			    {
				 s1.pop();
				 j++;
				}
				if(s1.empty())
				 break;
			}
			i++;
		}
		if(j!=b.length())
		 {
		 	cout<<"No."<<endl;
		 }
		else
		{
			cout<<"Yes."<<endl;
			i=0;
			j=0;
			while(i<a.length())
			{
				s2.push(a[i]);
				cout<<"in"<<endl;
				while(s2.top()==b[j])
				{
					if(!s2.empty())
					{
						s2.pop();
						cout<<"out"<<endl;
						j++;
					}
					if(s2.empty())
					 break;
				}
				i++;
			}
		}
		cout<<"FINISH"<<endl;
	}
	return 0;
 } 
 

单词的逆向输出
Sample Input
3
olleh !dlrow
m’I morf .efuxj
I ekil .mcaSample
Output
hello world!
I’m from jxufe.
I like acm.

#include<cstdio>
#include<iostream>
#include<stack>
using namespace std;
int main()
{
   int n;
   cin>>n;
   char k=getchar();
   while(n--)
   {
     stack<char> s;
     while(1)
     {
       char ch;
       ch=getchar();
       if(ch==' '||ch=='\n')
       {
        while(!s.empty())
        {
          cout<<s.top();
          s.pop();
        }
        if(ch=='\n')
         break;
        cout<<" ";
        }
        else
         s.push(ch);
    }
    cout<<endl;
  } 
    return 0;
}

三.Map

  • 头文件要求
#include<map>
using namespace std;
  • 常用操作
map<string,int> p;
/*<>里的内容是指什么类型的数据指向另一个类型,举个例子,map<string,int>month_name表示月份名字到月份编号的映射*/
  • 骚操作
  map<string,int>::iterator it;    /*相当于一个指向map的指针*/
  it=q.begin();      /*获得map的首地址*/
  it=q.end();        /*获得map的为地址*/
  it++;              /*地址加一*/
  it->second;        /*这个数值是指向int值*/
  it->first;         /*这个值是指向string值*/
  • 例题

在ACM比赛中,每个题目都会有一个相对应颜色的气球。每当你AC一道题目的时候,便会有一个气球升起。但是eternal太弱了又不想爆0,所以他每次都会去寻找AC数目最多的题目去做,请你帮他找到相应的颜色。

Input输入包含多组数据。每组数据第一行包含整数N (0 < N <= 1000) – 代表气球的总数. 接下来的N行每行包含一个颜色的单词. 单词最多由15个小写字母组成.

当N==0时代表输入结束,退出程序。

Output对每一组输入输出颜色代表这种颜色的气球数最多。数据保证存在答案。

Sample Input
5
green
red
blue
red
red
3
pink
orange
pink
0
Sample Output
red
pink

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		map<string,int>q;
		if(n==0)
		break;
		for(int i=0;i<n;i++)
		 {
		 	string s;
		 	cin>>s;
		 	q[s]++;
		 }
		 map<string,int>::iterator it;
		 int max=0;
		 string color;
		 for(it=q.begin();it!=q.end();it++)
		 {
		 	if(it->second>max)
		 	{
		 		max=it->second;
		 		color=it->first;
			 }
		 }
		 cout<<color<<endl;
	}
	return 0;
 } 

常见题型:
翻译词典类型
Sample Input
START
from fiwo
hello difh
mars riwosf
earth fnnvk
like fiiwj
END
START
difh, i’m fiwo riwosf.
i fiiwj fnnvk!
END
Sample Output
hello, i’m from mars.
i like earth!

#include<iostream>
#include<map>
using namespace std;
map<string,string> p;
int main()
{
 string a,b,c;
 cin>>a;
 while(cin>>b)
 {
  if(b=="END")
   break;
  cin>>c;
  p[c]=b;
 }
 cin>>a;
 getchar();
 string key;
 while(1)
 {
  key="";
  char ch;
  while(scanf("%c",&ch)!=EOF)
  {
   if(key=="END"&&ch=='\n')
    return 0;
   if(ch=='\n')
    break;
   if(isalpha(ch))
    key=key+ch;
   else
   {
    if(p.find(key)!=p.end())
     cout<<p[key];
    else
     cout<<key;
    cout<<ch;
    key="";
   }
  }
  cout<<endl;
  
 }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值