一.优先队列
- 头文件需求
#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;
}
}