UVa 10474
题意:给上面写有非负整数的大理石排序并查找指定的大理石位置
思路:扫入数组,用sort排序,查找(可以用“返回大于或等于x的第一个位置”的lower_bound函数)即可
UVa 101
题意:
输入n,得到编号为0~n-1的木块,分别摆放在顺序排列编号为0~n-1的位置。现对这些木块进行操作,操作分为四种。
1、move a onto b:把木块a、b上的木块放回各自的原位,再把a放到b上;
2、move a over b:把a上的木块放回各自的原位,再把a发到含b的堆上;
3、pile a onto b:把b上的木块放回各自的原位,再把a连同a上的木块移到b上;
4、pile a over b:把a连同a上木块移到含b的堆上。
当输入quit时,结束操作并输出0~n-1的位置上的木块情况
思路:
0.我们首先发现所有操作其实就是移回原来的位置,移动到新的位置,当然移动哪一个木块我们需要有个查找它在哪的过程(查找位置)。
1.再具体看四种操作,含onto的,都需要将b上方的归位,含move的都需要将a上方的归位,并且所有的都需要在归位后,将a及a以上的移动到b顶。
2.读入数据,进行初始化(把编号为i的木块放到i号位置),模拟操作,输出即可。
关于vector数组的使用几点说明:
vector<int> a[maxn] (每一个a[maxn]都是vector数组)
push_back(),pop_back()可以自动改变大小
需要只保留0~h的元素:resize(h+1)
UVa 10815
题意:找出一段文本里,不同的单词,按字典序输出
思路:
首先明白set的功能:每个元素最多只能出现一次(它还会自动排序),因此只要变成小写存入set即可
关于set的使用几点说明:
声明:set<string> dic;
插入元素:dic.insert(s)
补充迭代器:
迭代器(iterator),类似于指针的用法,下面是一个遍历的示例
set<string> dic;
for(set<string>::iterator it = dic.begin(); it != dic.end(); it++)
cout << *it <<endl;
UVa 156
题意:输入一些单词,找出所有满足如下条件的单词:该单词不能通过字母重排,得到输入文本的另外一个单词。在判断是否满足条件时,字母不分大小写,但在输出时应保留输入中的大小写,按字典序进行排序。
思路:
进行“标准化”,将输入的每个单词都转化成小写再进行排序,然后再放入map进行统计。
开一个vector数组储存出现的单词原型,开一个map储存“标准化”后的单词及其出现的次数
显然对于每个出现一次的单词就是我们想要的东西,不过输出是需要字典序的,再开一个vector存一下排序即可。
关于map的find()和count():
count():有返回的1,没有返回的0
find():有返回位置,没有返回end()
UVa 12096
题意:
一个栈计算机,输入的命令有如下几种:
PUSH:将空集{}压栈
DUP:将栈顶元素复制一份压入栈中
UNION:先进行两次弹栈,将获得的集合A和B取并集,将结果压栈
INTERSECTION:先进行两次弹栈,将获得的集合A和B取交集,将结果压栈
ADD:先进行两次弹栈,将获得的集合A和B中,先出栈的集合(如A先)加入到后出栈的集合,将结果压栈
输出每一步操作后栈顶集合的元素的个数。
思路:
开一个map:把集合映射成ID
开一个vector:根据ID去取集合
一个ID函数:查一下某个集合x的ID,如果查不到,就给它分配一个ID
开一个栈,模拟题目的操作
关于set的一些操作:
取并集:set_union(x1.begin(),x1.end(),x2.begin(),x2.end(),inserter(x,x.begin()))
依次传入两个集合的起始位置和结束位置,然后一个inserter迭代器,下作解释。
inserter(container,pos):在内部调用insert()成员函数,将元素插入第二个参数所指的位置。
set_intersection同理,不过是取交集操作。
UVa 540
题意:
t个团队排队,新来一个人,有队友排队,就插到最后一个队友后面,如果没有,就站到长队的队尾。输入队伍中所有队员的编号,要求支持以下三种指令:
ENQUEUE x:编号为x的人进队
DEQUEUE:长队队首出队
STOP:停止模拟
对于每个DEQUEUE指令,输出出队的人的编号。
思路:
显然,相同队伍的人会站在一起,开两个队列,一个存的是队伍编号(即大队伍),一个存的是每个小队伍里成员的站位(利用数组),再用一个map映射一下每个成员的所属队伍。
对于每个进来的人,先查他是哪个队的,再查他的队伍有没有人。
对于每个出去的人,先查队首是哪个队,让第一个人出去,再看看这个队出去一个人是不是空的,如果空了,让这个队出去。
UVa 136
题意:输出第1500个丑数
丑数:不能被2,3,5以外的素数整除的数(1也是丑数)
思路:对于任意丑数x,我们有2x,3x,5x都是丑数。利用优先队列取出最小的丑数,生成三个丑数(需要利用集合判重)。
代码实现:
const int coeff[3]={2,3,5};
int ugly()
{
priority_queue<long long int, vector<long long int>,greater<long long int> >pq;
set<long long int> s;
pq.push(1);
s.insert(1);
for(int i=1;i<n; i++)
{
long long int x=pq.top();
pq.pop();
for(int j=0; j<3; j++)
{
long long int x2=x*coeff[j];
if(!s.count(x2))
{
s.insert(x2);
pq.push(x2);
}
}
}
}
关于优先队列的一点补充:
对于常见的优先队列,STL提供了更为简单的定义方法,例如
“越小的整数优先级越高”——“priority_queue<int, vector<int>,greater<int> > pq”(最后的> >最好有空格)
当然,也是可以定义一个结构体cmp,去重载“()”运算符
例如,“个位数大的整数有限优先级反而小”——“priority_queue<int, vector<int>,cmp > pq”
struct cmp
{
bool operator()(const int a,const int b)const
{
//a的优先级比b小时返回true
return a % 10 > b % 10;
}
};