暂时在STL告一段落,用oj上的题目来告一段落小结,以后抽空补充了
第一题 词典
知识点:对map的使用:
find方法:用find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器;
cin.get 存储正在读取的字符;
cin.putback 将读取的字符放回去,让别人也可以读;
cin.get 和 cin.putback在这里的使用的意思是我先读取输入的第一个字符,判断它是不是回车,如果是回车跳出循环,不是则进入循环,然后把这个读取的字符放回去,防止后面的读不到这个字符。
#include<iostream>
#include<string>
#include<map>
#include<cstdio>
#include<algorithm>
#include<iterator>
using namespace std;
map<string,string> m;
map<string,string>::iterator it;\\ 指针
string a, b, c;
char tmp;
int main()
{
while( (tmp = cin.get()) != '\n' )\\判断输入的字符是不是回车
{
cin.putback(tmp);\\将字符放回去,让后面的也读取
cin >> a >> b;
m[b] = a;
cin.get();\\读入下一个输入的字符
}
while( cin >> c )
{
it = m.find(c);\\利用map中的find方法查找指定对象,
if( it != m.end() )\\判断是否找到
cout << it->second << endl;
else
cout << "eh" << endl;
}
return 0;
}
第二题
List
对List的使用:
push_back()
merge
unique
#include<iostream>
#include<list>
#include<algorithm>
#include<iterator>
using namespace std;
string s;
int id1, id2;
list<int> lis[200010];
int main()
{
int n;
cin >> n;
while( n-- )
{
cin >> s;
if( s == "new" ) cin >> id1; \\新建一个指定编号为id的序列(id<10000)
else if( s == "add" ) \\向编号为id1的序列加入整数id2
{
cin >> id1 >> id2;
lis[id1].push_back(id2);
}else if( s == "merge" ) \\merge id1 id2——合并序列id1和id2中的数,并将id2清空
{
cin >> id1 >> id2;
lis[id1].merge(lis[id2]);
}else if( s == "unique" ) \\去掉序列id中重复的元素
{
cin >> id1;
lis[id1].sort();\\需要实现排序,因为unique只可以去掉相邻的重复元素
lis[id1].unique();
}else
{
cin >> id1;
if( !lis[id1].empty() )
{
lis[id1].sort();
list<int>::iterator it;\\有两种输出方法,第一种指针,第二种自行去了解
it = lis[id1].begin();
for( ; it != lis[id1].end(); it++ )
cout << *it << " ";\\ *it呦
/*
ostream_iterator<int> output( cout, " " );
copy( lis[id1].begin(), lis[id1].end(), output );
*/
cout << endl;
}else
cout << endl;
}
}
return 0;
}
第三题
Set
multiset :可以插入完全相同的两条记录
set:不可以插入完全相同的两条记录
insert
count
erase
#include<iostream>
#include<set>
using namespace std;
string s;
int n;
int x;
multiset<int> a; \\操作
set<int> b; \\存储 判断
int main()
{
cin >> n;
while( n-- )
{
cin >> s >> x;
if( s == "add" )
{
a.insert(x);
b.insert(x);
cout << a.count(x) << endl;
}else if( s == "ask" )
{
if( b.count(x) )
cout << 1 << " ";
else
cout << 0 << " ";
cout << a.count(x) << endl;
}else
{
cout << a.count(x) << endl;
a.erase(x);
}
}
return 0;
}
第四题
热血格斗场
对map的使用:
lower_bound:返回第一个大于等于该元素的下标
upper_bound: 返回第一个大于该元素的下标
都是利用二分查找的方法在一个排好序的序列中进行查找的
不存在则返回end
pair的使用
#include<iostream>
#include<map>
#include<iterator>
using namespace std;
multimap<int, int> member;
multimap<int, int>::iterator i, j;
int n;
int main()
{
scanf( "%d", &n );
member.insert(pair<int, int>(1000000000, 1));
for( int k = 1; k <=n; k++ )
{
int id, power, adver = 1;
scanf( "%d %d", &id, &power );
i = member.lower_bound(power);
j = member.upper_bound(power);
if( i == member.begin() )\\ 如果在第一个
{
adver = i -> second;
}else if( i == member.end() ) \\ 如果没找到
{
i--;
adver = i -> second;
}else
{
i--;
if( power - i -> first <= j -> first - power )
adver = i -> second;
else
adver = j -> second;
}
printf( "%d %d\n", id, adver );
member.insert( pair<int, int>(power, id));
}
return 0;
}
第五题
冷血格斗场
#include<iostream>
#include<cstring>
#include<map>
#include<utility>
#include<cmath>
using namespace std;
//如果出现实力值相同的两个人,那么只存储结点号较小的
map<int,int>m;//实力值,id号
int n;
int main()
{
m[1000000000]=1;
cin>>n;
for(int i=1;i<=n;i++)
{
int id,x;cin>>id>>x;
auto it=m.lower_bound(x);//寻找第一个大于等于当前实力值的;
//特判
if(it==m.begin())
{
cout<<id<<" "<<it->second<<endl;
}//特判
else if(it==m.end())
{
cout<<id<<" "<<(--it)->second<<endl;
}
else
{//it和--it处一定是取得最接近实力值的位置
int iid=it->second;int xx=it->first;
--it;
if(abs((it->first)-x)<abs(x-xx)){
cout<<id<<" "<<it->second<<endl;
}
else if(abs((it->first)-x)==abs(x-xx))
cout<<id<<" "<<min(iid,it->second)<<endl;
else cout<<id<<" "<<iid<<endl;
}
//如果实力值相同,存储结点值比较小的
if(m.find(x)!=m.end()){
m[x]=min(m[x],id);
}
else m[x]=id;
}
return 0;
}
以后再改改,有错误的地方还请批评指正