时间限制:1秒
空间限制:32768K
输入描述:
首先输入一个正整数N(N <= 50),接下来输入N个数表示每顶帽子的价格(价格均是正整数,且小于等于1000)
输出描述:
如果存在第三便宜的帽子,请输出这个价格是多少,否则输出-1
输入例子1:
10 10 10 10 10 20 20 30 30 40 40
输出例子1:
30
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
int buf[1000];
for (int i = 0; i < n; i++)
{
cin >> buf[i];
}
sort(buf,buf+n);
int count = unique(buf, buf + n) - buf;
if (count>2)
{
cout << buf[2] << endl;
}
else
{
cout << -1 << endl;
}
system("pause");
return 0;
}
涉及函数:sort(起始地址,结束地址,比较规则),需事先声明#include<algorithm>和using namespace std;
比较规则可以自己定义,默认从小到大排序。
若从大到小降序排序,可自行定义规则
bool cmp(int a, int b)
{
return a > b;
}
unique(起始地址,结束地址),返回值为不重复的元素的个数。
若使用vector向量作为数组,还可以使用函数erase擦除最后重复的元素,由于unique函数只可以去除相邻的相等值元素并放在末尾,所以使用之前必须进行排序,若真正去除,还要使用erase函数。
unique函数是一个去重函数,去除相邻中的重复元素(只留一个)。
其中,最关键的是:并不是删除并不是把重复的元素删除,而是全部放倒数组的后面。
因为,unique只是去除(相邻)的重复元素,因此,为了去除重复的元素,应该,首先对数组/Vector进行排序,这样保证重复元素在相邻的位置。
unique函数,返回的是去重后的尾地址。
因此对于一个内容为{2, 2, 5, 5, 6}的vector,执行unique函数以后,vector大小并没有改变,只不过顺序变成了{2, 5, 6, 2, 5},并且函数的返回值为:3。
此时需要删除重复元素,只需要将后面的数据全部删除即可。
排序函数(sort)和去重函数都在<algorithm>头文件中。
1 #include <iostream> 2 #include <algorithm> 3 #include <vector> 4 using namespace std; 5 6 7 int main() { 8 vector<int> v; 9 cout << "Number of vector's element : " << endl; 10 int number; 11 cin >> number; 12 for (int i = 0; i < number; i++) { 13 int temp; 14 cin >> temp; 15 v.push_back(temp); 16 } 17 sort(v.begin(),v.end()); 18 v.erase(unique(v.begin(), v.end()), v.end()); 19 for (int i = 0; i < v.size(); i++) { 20 cout << v[i] << " "; 21 } 22 cout << endl; 23 return 0; 24 }
unique()函数将重复的元素放到vector的尾部 然后返回指向第一个重复元素的迭代器再用erase函数擦除从这个元素到最后元素的所有的元素
erase函数的原型如下:
(1)string& erase ( size_t pos = 0, size_t n = npos );
(2)iterator erase ( iterator position );
(3)iterator erase ( iterator first, iterator last );
也就是说有三种用法:
(1)erase(pos,n); 删除从pos开始的n个字符,比如erase(0,1)就是删除第一个字符
(2)erase(position);删除position处的一个字符(position是个string类型的迭代器)
(3)erase(first,last);删除从first到last之间的字符(first和last都是迭代器)
下面给你一个例子:
#include <string>
using namespace std;
int main ()
{
string str ("This is an example phrase.");
string::iterator it;
// 第(1)种用法
str.erase (10,8);
cout << str << endl; // "This is an phrase."
// 第(2)种用法
it=str.begin()+9;
str.erase (it);
cout << str << endl; // "This is a phrase."
// 第(3)种用法
str.erase (str.begin()+5, str.end()-7);
cout << str << endl; // "This phrase."
return 0;
}
erase()函数的功能是用来删除容器中的元素
删除某个容器里的某个元素:c.erase(T);
看似一个简单的动作,然而对不同类型的容器,内部却做了截然不同的事情,后面介绍。 假设有这样一个题目,将某个容器中所有满足条件N == X的元素删除,按照常规的思路应该有类似这样的代码:
// 假设Container和container分别表示一种容器和对应的一个对象
Container<T>::iterator it;
for (it = container.begin(); it != container.end(); ++it) {
if (N == X)
container.erase(it);
}
然而这样的代码对于任一种容器都是错误的
容器按内存分配方式可以分为链表容器和数组容器。
所谓的链 表容器指的是一种表现方式,包括list、slist等这样基于节点的容器(动态分配内存块)和set、map、multiset、multimap等关 联容器(平衡树实现),而数组容器指的是在一块连续的内存上保存元素的连续内存容器,比如vector、deque、string等。
链表容器 以list为例,当执行container.erase(it)时,确实第一个满足条件的元素删除了,但这时it指针已经被删除了,它也不指向任何元素 了,所以也只能到此为止了,也就是说上面的代码对于链表容器来说只能正确删除第一个满足条件的元素,针对这个问题我们首先想到的就是在删除指针之前,给其 做个备份。
将这个临时变量直接建立在erase实现里,这样做更简洁,也显得专业些。
list<int>::iterator it;
for (it = lt.begin(); it != lt.end(); ) {
if (*it % 2 == 0)
lt.erase(it++); //这里是关键
else
++it;
}
链表容器使用erase删除节点还有一个特点,就是会将下一个元素的地址返回,所以也可以这样实现:
list<int>::iterator it;
for (it = lt.begin(); it != lt.end(); ) {
if (*it % 2 == 0)
it = lt.erase(it);//自动返回下一个元素的地址,不用再主动前移指针
else
++it;
}
vector<int>::iterator it = v.begin();
for (it = v.begin(); it != v.end(); ) {
if (*it % 2 == 0)
v.erase(it);//删除元素后,后面元素自动往前移,不用挪动指
else
++it;
}
网上有说在VS2005里面上面的v.erase(it)写法是行的 VS2008及2010却运行会出现错误 会出现
vector erase iterator outside range 最保险的做法是将v.erase(it)改成 it=v.erase(it)