STL 是一个库,可直接 调用 ,里面的 很多东西 都可以 来用,并可以来简化问题,例如 stack ,queue,set,multiset,map,multimap,vector, 能 极大 简化问题 。具体的 用法就不过多 介绍。
1.stack 先进后出 ,可以用来 做 那些 正着 入栈,倒着出栈,就很大的减少了 再遍历一次倒着 输出 ,可以直接 stack 输出 ,并且 还可对当前的 数据 出栈,进而对更 多的要求 得到满足 ,屡试不爽。
例题 :Text Reverse HDU 1062
题面:信管ACM协会的陈萧伊学长是一个写微信的好手,不过他写微信的时候会有一个特殊的习惯,文字中如果要用到英语的话,会把所有的单词都倒过来写,他说是这样就可以灵感爆发。但是这样我们协会负责微信的小委员会很头疼,他们要在截止交稿之前把所有的单词都倒回来,痛苦万分啊!你可以帮帮这个可怜的小委员么?
INPUT
本题输入包含多组测试样例。
第一行是一个整数T,表示输入样例的个数,之后跟着T行,每行即为一个样例。
每一个样例都是一个句子,其中包含很多单词。题目保证每一个句子的总长度不超过1000。
OUTPUT
对于每个样例,请你把单词都倒回来
Sample Input
3
olleh !dlrow
m'I morf .efuxj
I ekil .mca
Sample Output
hello world!
I'm from jxufe.
I like acm.
代码:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<stack>
using namespace std;
typedef long long ll;
const int maxn=1005;
char a[maxn];
stack<char>s;
int main()
{
int t,i;
cin>>t;
getchar();
while(t--)
{
memset(a,0,sizeof(a));
gets(a);
for(i=0;a[i];i++)
{
if(a[i]==' ')
{
while(!s.empty())
{
printf("%c",s.top());
s.pop();
}
cout<<' ';
continue;
}
s.push(a[i]);
}
while(!s.empty())
{
printf("%c",s.top()); //是输出最后的一段 没有空格的栈里的元素。
s.pop();
}
cout<<endl;
}
return 0;
}
2. queue 先进先出 ,对于一些数据 要做某些 要求 ,并且 输出 这一串 数据 ,可以用 queue 来模拟 ,在数据 满足时 ,压入队列,用完后 再弹出 ,轻松利用 ,灵活自如,对于 一些 数据 进行很多 操作时,普通的 数组(或者 字符串)很难实现时,就可以 用 STL 的 队列 实现。
例题: Encoding HDU 1020
题面:
王和兴老师嫌弃ZZW平时说话过于啰嗦,扔给他一套说话转换法。
给定一个只包含“a”-“Z”的字符串,我们可以使用以下方法对其进行编码:
1。每个包含k个相同字符的子字符串都应该编码为“kX”,其中“X”是该子字符串中唯一的字符。
2。如果子字符串的长度是1,则应忽略'1'。
输入
第一行包含一个整数N (1 <= N <= 100),它表示测试用例的数量。接下来的N行包含N个字符串。每个字符串仅由“A”-“Z”组成,长度小于10000。
输出
对于每个测试用例,在一行中输出编码的字符串。
样例输入
2
ABC
ABBCCC
样例输出
ABC
A2B3C
代码:
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=105;
char a[maxn];
queue<char>s;
int main()
{
int t,k=1,i,flag;
cin>>t;
while(t--)
{
k=1;
memset(a,0,sizeof(a));
cin>>a;
int j=0;
s.push(a[0]);
for(i=1;a[i];i++)
if(a[i]==s.front())
k++;
else
{
if(k==1)
cout<<s.front();
else
cout<<k<<s.front();
k=1;
s.pop();
s.push(a[i]);
}
if(k==1) //这是最后的操作,输出最后一次判断的情况
cout<<s.front();
else
cout<<k<<s.front();
while(!s.empty())
s.pop();
cout<<endl;
}
return 0;
}
3. set 容器 是很常用的STL 功能多 ,元素之间可以 互异 ,受到大家的喜爱。例如 查找存在还是不存在,重复元素,移除元素,迭代器,查找大于等于和 大于 的第一个元素,元素之间是递增的,也可以是递减的 ,根据 题目要求。
例题:
HDU 人见人爱A-B 水题
题面:
Problem Description
参加过上个月月赛的同学一定还记得其中的一个最简单的题目,就是{A}+{B},那个题目求的是两个集合的并集,今天我们这个A-B求的是两个集合的差,就是做集合的减法运算。(当然,大家都知道集合的定义,就是同一个集合中不会有两个相同的元素,这里还是提醒大家一下)
呵呵,很简单吧?
Input
每组输入数据占1行,每行数据的开始是2个整数n(0<=n<=100)和m(0<=m<=100),分别表示集合A和集合B的元素个数,然后紧跟着n+m个元素,前面n个元素属于集合A,其余的属于集合B. 每个元素为不超出int范围的整数,元素之间有一个空格隔开.
如果n=0并且m=0表示输入的结束,不做处理。
Output
针对每组数据输出一行数据,表示A-B的结果,如果结果为空集合,则输出“NULL”,否则从小到大输出结果,为了简化问题,每个元素后面跟一个空格.
Sample Input
3 3 1 2 3 1 4 7
3 7 2 5 8 2 3 4 5 6 7 8
0 0
Sample Output
2 3
NULL
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
const int maxn=105;
set<int>s;
int a[maxn];
int main()
{
int n,m,i,num;
set<int>::iterator x;
while(cin>>n>>m)
{
s.clear();
memset(a,0,sizeof(a));
if(n==0&&m==0)
break;
for(i=0;i<n;i++)
{
cin>>num;
s.insert(num);
}
for(i=0;i<m;i++)
{
cin>>a[i];
x=s.find(a[i]);
if(x!=s.end())
s.erase(*x);
}
if(s.size()==0)
cout<<"NULL"<<endl;
else
{
for(auto it=s.begin();it!=s.end();it++)
cout<<*it<<' ';
cout<<endl;
}
}
return 0;
}
4. 统计难题 HDU - 1251
题面 :
Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).
Input
输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.
注意:本题只有一组测试数据,处理到文件结束.
Output
对于每个提问,给出以该字符串为前缀的单词的数量.
Sample Input
banana
band
bee
absolute
acm
ba
b
band
abc
Sample Output
2
3
1
0
#include <stdio.h>
#include <string.h>
#include <map>
#include <string>
using namespace std;
map<string,int>m1;
int main()
{
char z[10];
while(gets(z))
{
if(strlen(z)==0)
break;
for(int i=strlen(z);i>0;i--)
{
z[i]='\0';
m1[z]++;
}
}
while(gets(z))
{
printf("%d\n",m1[z]);
}
return 0;
}
上面有个 空行条件 ,就是 strlen(z) 小于0 ,就可以来判断。
这道题 是找出 与 问题字符串前缀匹配的 数量,仔细想一想 ,是个 映射 的问题 ,直接找到 每个字符串 有多少前缀,并且 有几个 是相同的 ,用到 map<string,int> ,用 数组 的形式 进行 插入 。如果用暴力做,很容易超时,map 解法简单。