STL(Standard Template Library)
在程序设计竞赛中,偶尔会碰到一些需要用特殊结构来解决的问题,这时,灵活运用STL库中的一些数据结构会加速问题的解决,这里,我写了一些我碰到过的应用案例,帮助理解STL的强大。
虽然这些特殊的结构可以解决很多问题,但是性能较差,对于一些时间、空间性能要求比较高的题目并不适用。
目录
STL(Standard Template Library)
Windows Message Queue HDOJ - 1509
The kth great number HDOJ - 4006
set
简单介绍:说白了就是一个元素不会重复的容器,比如你往容器里放一个集合{1,1,2},容器里就只会有{1,2},也就是这里面的每个元素值都是唯一的,而且系统会根据元素的值对元素进行排序,但是容器里的元素值不能直接被改变。
具体怎么使用:相关的函数及其使用细节请自行搜索~这些就不在这里赘述了,这里就只放一些题目和解决方法。
单词数 HDOJ - 2072
题意:输入一篇文章,文章内的单词间用空格隔开,文章以符号“#”结束,计算文章内不重复的单词数并输出结果。
分析:利用set容器的特点,将文章的所有单词都存到set容器里,在遇到结束符号的时候输出max_size。
AC代码:
//HDOJ - 2072
#include<iostream>
#include<cstdio>
#include<set>
#include<cstring>
#include<sstream>
using namespace std;
char s[1000000];
int main()
{
while(gets(s))
{
set<string>p;//set是关联容器,里面的元素不会重复
if(!strcmp(s,"#"))
break;
stringstream ss(s);
string di;//
while(ss>>di)//遇到空格截断,把ss里的内容复制到di里
p.insert(di);//元素插入
cout<<p.size()<<endl;//容器里的元素个数
}
return 0;
}//MIC_H
map
简单介绍:一个映射容器,以键值对(key-value)为单位存储元素,key值必须唯一,value值可以重复,且容器有自动排序的特点。
用数组来帮助理解,数组可以用a[0]来获取数组里位置0的元素,此时0就是key,a[0]就是value,数组和map不同的是,map里面的key可以用其他数据类型来定义,如string等,例如可以用map来存储一群人的名字和对应的年龄,通过他们的名字可以获得他们的年龄值。
具体怎么使用:相关的函数及其使用细节请自行搜索~这些就不在这里赘述了,这里就只放一些题目和解决方法。
Shopping HDOJ - 2648
题意:一开始输入n个店的店名,然后输入天数,要求输出每一天memory的排名(从大到小)。
分析:每一天都遍历集合里的元素(),memory的初始rank为1,当遇到比memory的价格大的店时,rank+1,遍历完所有的店之后,此时的rank就是这一天memory的排名。
AC代码:
//HDOJ - 2648
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <functional>
#include <cmath>
#include <map>
#include <vector>
#include <set>
#include <climits>
#include <string>
using namespace std;
map<string,int>mp;///商店名字为key,每天更新商店的价格
string name[10009];
int main()
{
int n,m,num;
while(cin>>n)
{
for(int i=0;i<n;i++)
{
cin>>name[i];
mp[name[i]]=0;
if(name[i]=="memory")
num=i;///方便写代码,也可以不这样写
}
cin>>m;
while(m--)
{
string ss;
int rank=1;
int rise;
for(int i=0;i<n;i++)
{
cin>>rise>>ss;
mp[ss]+=rise;
}
for(int i=0;i<n;i++)///遍历,找多少家商店的价格比memory的高
if(mp[name[i]]>mp[name[num]]) ///比memory的高,memory的排名就+1
rank++;
cout<<rank<<endl;
}
}
return 0;
}//MIC_H
Intelligent IME HDOJ - 4287
题意:给出输入顺序和字典,要求输出在字典里找到的匹配单词的个数。
分析:用数组ch记录各个字母的键盘位置,然后每输入一个单词就对相应的字符串映射的值++,最终各个输出。
AC代码:
//HDOJ - 4287
#include <iostream>
#include <cstdio>
#include <string>
#include <map>
#define mod 10007
using namespace std;
char ch[30]={'2','2','2','3','3','3','4','4','4','5','5','5'
,'6','6','6','7','7','7','7','8','8','8','9','9','9','9'};
map<string,int> ma;
string a[5050];
int main()
{
int t,n,m;
string s1,s2;
cin>>t;
while(t--)
{
cin>>n>>m;
for(int i=0;i<n;i++)
{
cin>>s1;
a[i]=s1;
ma[s1]=0;
}
for(int i=0;i<m;i++)
{
cin>>s1;
s2="";
for(unsigned j=0;j<s1.size();j++)//将单词转换成输入顺序
s2+=ch[s1[j]-'a'];
ma[s2]++;
}
for(int i=0;i<n;i++)
cout<<ma[a[i]]<<endl;
}
return 0;
}//MIC_H
水果 HDOJ - 1263
题意:给出一组数据,每行数据分别包括水果名称、水果产地、水果销量,要求输出每个产地各种水果的销售量。
分析:映射关系为地名->水果->销售数目,需要用两个map嵌套实现,每输入一行数据,就更新map,具体见代码。
AC代码:
//HDOJ - 1263
#include<iostream>
#include<string>
#include<map>
using namespace std;
struct MyStruct
{
map <string, int>MyStructma; //存放水果名以及该种水果的数量
};
int main()
{
map <string, MyStruct>ma; //地名
map <string, MyStruct>::iterator it;
map <string, int>::iterator MyStructmait;
string fruit,place;
int count;
int n,t;
cin>>t;
while(t--)
{
ma.clear();
cin>>n;
while(n--)
{
cin>>fruit>>place>>count;
ma[place].MyStructma[fruit] += count;
}
for (it = ma.begin(); it != ma.end(); it++)
{
cout<<it->first<<endl;
for (MyStructmait = it->second.MyStructma.begin(); MyStructmait != it->second.MyStructma.end(); MyStructmait++)
{
cout<<" |----"<<MyStructmait->first<<"("<<MyStructmait->second<<")"<<endl;
}
}
if(t != 0)cout<<endl;
}
return 0;
}//MIC_H
优先队列 priority_queue
简单介绍:特点是队列最大的元素总是在队首(默认情况),每插入一个元素,队列就会进行调整。可以自己设置队列里面的排序规则。
具体怎么使用:相关的函数及其使用细节请自行搜索~这些就不在这里赘述了,这里就只放一些题目和解决方法。
Windows Message Queue HDOJ - 1509
题意:输入一系列GET和PUT命令,要求显示输出结果。当命令是PUT时,无输出,当命令是GET时,若此时队列不为空,则获取优先级最高的消息并输出,若队列为空,则显示"EMPTY QUEUE!"。
分析:用优先队列对输入的PUT消息里的内容进行排序,排序根据为优先级和时间顺序,优先级一致时,时间顺序靠前的排名较高。具体见代码。
AC代码:
//HDOJ - 1509
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <map>
#include <queue>
#define mod 10007
using namespace std;
struct message
{
string name;
int val;
int ran;
int t;
friend bool operator < (message m1,message m2)//优先队列里的排序规则
{
if(m1.ran!=m2.ran)
return m1.ran > m2.ran;
else
return m1.t>m2.t;
}
};
int main()
{
priority_queue<message>m;
string ope;
int time=0;
message mm;
while(cin>>ope)
{
if(ope=="GET")
{
if(m.empty())
printf("EMPTY QUEUE!\n");
else
{
cout<<m.top().name<<' '<<m.top().val<<endl;
m.pop();
}
}
else
{
cin>>mm.name>>mm.val>>mm.ran;
mm.t=++time;
m.push(mm);
}
}
return 0;
}//MIC_H
The kth great number HDOJ - 4006
题意:输入n和k,分别代表接下来有n个操作,如果是I操作,就是向队列里插入元素,如果是Q操作,就是输出第k大的元素。
分析:保证队列里最多只有k个元素,个数小于k则插入队列,若队列元素个数已为k,判断此时想要插入的元素是否大于队列中的最小值(队尾元素),如大于则把队尾元素删除,插入此yuan's,这样,队尾就会是第k大的值。
AC代码:
//HDOJ - 4006
#include <stdio.h>
#include <iostream>
#include <string>
#include <string.h>
#include <set>
#include <queue>
#include <sstream>
using namespace std;
int main()
{
int i,n,wro;
unsigned k;
char ope;
while(cin>>n>>k)
{
priority_queue<int,vector<int>,greater<int> >nn;
for(i=0;i<n;i++)
{
cin>>ope;
if(ope=='I')
{
cin>>wro;
if(nn.size()<k)
nn.push(wro);
else if(nn.top()<wro)
{
nn.pop();
nn.push(wro);
}
}
else
cout<<nn.top()<<endl;
}
}
return 0;
}//MIC_H
=======最后更新时间:2019.07.26=======
=======遇到好的题目会回来继续更新======
===如果各位大牛牪犇路过发现问题欢迎反映 (「・ω・)「嘿===