蓝桥杯第一次培训--stl

vector


vector被翻译为向量也称作变长数组

vector的定义

使用vector要记得加上头文件 #include<vector>
vector<typename> name;

vector<int> vi;
vector<double> vi;
vector<char> vi;
vector<node> vi;//node可以是结构体

vector是一个类似于int a[]的整数数组,而vector是一个类似于string a[]的字符串数组
它是基于倍增的思想的变长数组

基本常用的一些方法
clear()清空
resize()改变大小
push_back()在尾部添加元素
pop_back()在尾部删除元素
empty()测试是否为空
vector之间可以直接赋值或者作为函数的返回值
push_back()和pop_back()无需改变数组长度,自动会增加和减小数组长度

push_back(x)
在vi的元素末尾添加一个元素x

for(int i=0;i<5;i++)
   {
    
    
       vi.push_back(i);
   }
   
  for(int i=0;i<vi.size();i++)
  {
    
    
      cout<<vi[i]<<" ";  //0 1 2 3 4 
  }

vector可以直接赋值,可以通过下标直接访问

#include <bits/stdc++.h>

using namespace std;

int main()
{
    
    
   vector<int> vi;
   vector<int> b;
   for(int i=0;i<5;i++)
   {
    
    
       vi.push_back(i);
   }
   
   b=vi;
   for(int i=0;i<b.size();i++)
   {
    
    
      cout<<b[i]<<" ";
     

   }
   return 0;


}

size
返回vector中元素的个数

 for(int i=0;i<5;i++)
   {
    
    
       vi.push_back(i);
   }
   cout<<vi.size()<<endl;  //5

clear
清空vector数组中的全部元素

for(int i=0;i<5;i++)
   {
    
    
       vi.push_back(i);
   }
   vi.clear();//清空了
   cout<<vi.size()<<endl;//长度0
   return 0;

empty()
判断vector是否为空

for(int i=0;i<5;i++)
   {
    
    
       vi.push_back(i);
   }
   cout<<vi.empty()<<endl;//0
   vi.clear();//清空了
   cout<<vi.size()<<endl;//0
   cout<<vi.empty()<<endl;//1 因为调用了clear

大家想想empty这个函数和前面的那个函数有相同的作用?

back() 返回vector里的最后一个元素
front() 返回vector里的第一个元素

 for(int i=0;i<5;i++)
   {
    
    
       vi.push_back(i);
   }
   cout<<vi.front()<<endl;//0
   cout<<vi.back()<<endl;//4

pop_back()
删除vector尾元素

 for(int i=0;i<5;i++)
   {
    
    
       vi.push_back(i);
   }
   vi.pop_back();//删除最后一项
   for(int i=0;i<vi.size();i++)
   {
    
    

       cout<<vi[i]<<" ";//0 1 2 3
   }

vector的遍历
1.通过下标方式遍历

for(int i=0;i<5;i++)
   {
    
    
       vi.push_back(i);
   }
   for(int i=0;i<vi.size();i++)//通过下标方式遍历
   {
    
    

       cout<<vi[i]<<" ";//0 1  2 3 4
   }

2.通过迭代器遍历

vector<typename>::iterator it可以把它看做类似于指针的东西
vi[i](vi.begin()+i)是等价的
vi.begin()和vi.end()是左开右闭的end()表示的是尾元素的下一个 
迭代器支持++,--的操作
迭代器不支持it<end()写法,因此循环条件只能用it !=vi.end()
 for(vector<int>::iterator it=vi.begin();it!=vi.end();it++)
   {
    
    

           cout<<*it<<" ";//0 1  2 3 4

   }
   

在常用的stl容器中只有vector和string中才允许使用vi.begin+整数 这种写法
insert()
向vector的任意迭代器it处插入一个元素x
注意第一个参数必须是迭代器

 for(int i=0;i<5;i++)
   {
    
    
       vi.push_back(i);
   }
   vi.insert(vi.begin()+2,8);//在下标为2的地方插入8
   for(int i=0;i<vi.size();i++)
   {
    
    

       cout<<vi[i]<<" ";//0 1 8 2 3 4
   }

vector和algorithm里面的函数的应用

//reverse() 倒置 是在algorithm里面的函数 
	//12345
	reverse(vi.begin(),vi.end());
		for(vector<int>::iterator it=vi.begin();it!=vi.end();it++){
    
    
    	 cout<<*it<<" ";//5,4,3,2,1
	}
	cout<<endl;
	
	//sort()排序默认是从小到大排 还可以任意排序后面讲 
	sort(vi.begin(),vi.end());
	 	for(vector<int>::iterator it=vi.begin();it!=vi.end();it++){
    
    
    	 cout<<*it<<" ";//1,2,3,4,5
	}

string


string类的定义
定义string类的方式跟基本数据类型相同,只需要在string后跟上变量名即可

string str;
如果要初始化,可以直接给string类进行赋值
string str="hello";

string类的访问
直接通过下标访问

string str="abcdef";
  for(int i=0;i<str.length();i++){
    
    
  	 cout<<str[i];
  }	

如果要读入和输出字符串只能用cin和cout

 cin>>str;
 cout<<str;

如果读入带有空格等等的字符串

getline(cin,str);

如果要用printf输出string类型

printf("%s",str.c_str());

通过迭代器访问

for(string::iterator it=str.begin();it!=str.end();it++){
    
    
		   cout<<*it;
	}

string和vector 一样,支持直接对迭代器进行加减某个字数str.begin()+i

string类可以直接进行加法,可以将两个string类拼接起来
string类可以直接比较大小 是按字典序排的

length() size() 返回string的长度

string str="abcdef";
cout<<str.length()<<endl;//6
cout<<str.size()<<endl;//6

insert()
insert(pos,string) 在pos号位置插入字符串string

 string str1="abc";
	string str2="ddd";
	str1.insert(1,str2);
	cout<<str1<<endl;//adddbc

这里和之前讲的vector对比一下vector第一个参数的迭代器而string的是位置

insert(it,it2,it3) it为原字符串欲插入的位置 it2和it3为待插字符串的首位

//insert(it,it2,it3) it为原字符串欲插入的位置 it2和it3为待插字符串的首尾迭代器
	string str3="abcde";
	string str4="fghi";
	str3.insert(str3.begin()+3,str4.begin(),str4.begin()+2); 
	cout<<str3<<endl;//abcfgde

erase()
erase() 有两种用法一种是删除单个元素另一种是删除一个区间的所有元素

删除单个元素 erase(it) 用于删除单个元素 it为要删除的元素的迭代器

	
//	删除单个元素  erase(it) 用于删除单个元素 it为要删除的元素的迭代器 
    string s1="abcdef";
	s1.erase(s1.begin()+3);
	cout<<s1<<endl;//abcef
	

删除一个区间内的所有元素
str.erase(first,last) first为要删除区间的其实迭代器,last为需要删除的末尾迭代器的下一个地址
str.erase(pos,length) pos为要删除的起始地址 length为要删除的字符个数

//删除一个区间内的所有元素 
	//str.erase(first,last) first为要删除区间的其实迭代器,last为需要删除的末尾迭代器的下一个地址 
	 string s2="abcdef";
	 s2.erase(s2.begin(),s2.begin()+4);
	 cout<<s2<<endl;//ef 
	 
	//str.erase(pos,length) pos为要删除的起始地址 length为要删除的字符个数 
	string s3="abcdef";
	s3.erase(2,4);
	cout<<s3<<endl;//ab 

clear()
清空string中的数据

s3.clear();
cout<<s3<<endl;
cout<<s3.length();

find()
str.find(str2) 当str2是str的子串时,返回其在str中第一次出现的位置,如果str2不是str的子串返回-1

str.find(str2,pos)从str的pos号位开始匹配str2


	 //str.find(str2) 当str2是str的子串时,返回其在str中第一次出现的位置,如果str2不是str的子串返回-1 
	  string ss1="abcdefabc";
	  string ss2="abc";
	  int pos=ss1.find(ss2);
	  cout<<pos<<endl;//0
	  
	 //str.find(str2,pos)从str的pos号位开始匹配str2
	  int pos1=ss1.find(ss2,3); 
	  cout<<pos1<<endl;//6
	  int pos2=ss1.find("xyz");
	  cout<<pos2<<endl;//-1

stack


大家刚学完数据结构是不是每次用栈和队列都很麻烦还要建链表…stl真的很方便帮我们都写好了直接用。。。。 懒狗的福音哈哈

stack是栈一种先进后出的容器,理解就是书从上往下堆,如果想拿下面的书必须先把上面的书拿开
要使用必须加头文件 #include
stack的定义

stack<typename> name

push
将元素压入栈
top()
取出栈顶元素
pop
弹出栈顶元素
stack不能通过下标访问,只能通过top()来取栈顶元素访问

 for(int i=0; i<5;i++)
  {
    
    
      st.push(i);
  }
  cout<<st.top()<<endl;//4
   st.pop();
  cout<<st.top()<<endl;//3

empty
判断栈是否空

for(int i=0; i<5;i++)
  {
    
    
      st.push(i);
  }
  cout<<st.empty()<<endl;//0 非空

size
获取stack内的元素

for(int i=0; i<5;i++)
  {
    
    
      st.push(i);
  }
  cout<<st.empty()<<endl;//0 非空
  cout<<st.size()<<endl;//5

判断非空也可以用size

if(st.size()>0{
    
    
   栈非空
}

清空栈
注意栈没有clear()方法只能遍历清空

while(st.size()>0)
  {
    
    
      st.pop();
  }
  cout<<st.empty()<<endl;//1
  cout<<st.size()<<endl;//0

queue 队列是stl中的一个先进先出的容器,理解就是食堂打饭,前面的人打完了先走后面的人接着排队


队列是stl中的一个先进先出的容器,理解就是食堂打饭,前面的人打完了先走后面的人接着排队

queue的定义

queue<typename> name;

typename可以是任意基本数据类型和容器 

队列是一种先进先出的限制性数据结构

q.push(x)将x进行入队

queue<int> q;
	//q.push(x)将x进行入队 
	 q.push(1);
	 q.push(2);
	 q.push(3);

stl中只能通过front()来访问队首元素,或者通过back()来访问队尾元素

queue<int> q;
	//q.push(x)将x进行入队 
	 q.push(1);
	 q.push(2);
	 q.push(3);
	 
	cout<<q.front()<<" "<<q.back()<<endl; //1 3

pop()
令队首元素出对

queue<int> q;
	//q.push(x)将x进行入队 
	 q.push(1);
	 q.push(2);
	 q.push(3);
	 
	cout<<q.front()<<" "<<q.back()<<endl; //1 3
	q.pop();
	cout<<q.front()<<endl; //2 

empty()
empty()检测queue是否为空

	queue<int> q;
	 
	 q.push(1);
	 q.push(2);
	 q.push(3);
	 cout<<q.empty()<<endl;//0

q.size()
返回队列中元素的数量

queue<int> q;
	 
	 q.push(1);
	 q.push(2);
	 q.push(3);
	 cout<<q.empty()<<endl;//0 
	 cout<<q.size()<<endl;//3
	 while(q.size()){
    
    
	 	q.pop();
	 }
	 cout<<q.empty()<<endl;//1

队列的清空
队列也是没有clear()函数的如果想要清空还是得遍历

while(q.size()>0)
  {
    
    
      q.pop();
  }
  cout<<q.empty()<<endl;//1
  cout<<q.size()<<endl;//0

优先队列
priority queue
也就是堆的概念,这里先不讲到时候讲到具体的算法时候再讲

set

set翻译为集合,是一个内部自动有序且不含重复元素的容器
set的定义

set<typename> name;

set<int> vi;
set<double> vi;
set<char> vi;
set<node> vi;//node可以是结构体

set<int> a[100]; //数组里面每个元素都是一个set集合

insert(x) 将x插入set容器中,并自动递增排序和去重

	//insert(x) 将x插入set容器中,并自动递增排序和去重
	st.insert(4);
	st.insert(3);
	st.insert(1);
	st.insert(2);
	//不支持<it.end()的写法
	for(set<int>::iterator it=st.begin();it!=st.end();it++){
    
    
		cout<<*it<<" ";//1 2 3 4
	}

set集合的遍历
set只能通过迭代器遍历
除了vector和string之外的stl容器都不支持*(it+i)的访问方式
set内的元素会自动递增排序,且自动去除了重复元素

//不支持<it.end()的写法
	for(set<int>::iterator it=st.begin();it!=st.end();it++){
    
    
		cout<<*it<<" ";//1 2 3 4
	}

find(value
返回set中对应值为value的迭代器

set<int>::iterator it=st.find(3); //查找值为3的元素返回其迭代器 
	cout<<*it<<endl; //如果查找的元素不存在会返回最后一个元素的迭代器 

erase()删除元素


//erase() 有两种用法一种是删除单个元素另一种是删除一个区间的所有元素
	//删除单个的方法又有两种
	//1.st.erase(it) it为所删元素的迭代器 可以和find连用 
	 //1 2 3 4
	st.erase(st.find(3)); 
	for(set<int>::iterator it=st.begin();it!=st.end();it++){
    
    
		cout<<*it<<" ";//1 2 4
	}
	cout<<endl;
	//2.st.erase(value) value为所删除元素的值 
	//1 2 4
	st.erase(1);
	for(set<int>::iterator it=st.begin();it!=st.end();it++){
    
    
		cout<<*it<<" ";//2 4
	}
	cout<<endl;
	st.insert(4);
	st.insert(3);
	st.insert(1);
	st.insert(2);
	//删除整个区间 
	//1 2 3 4
	st.erase(st.find(2),st.end());
	
	for(set<int>::iterator it=st.begin();it!=st.end();it++){
    
    
		cout<<*it<<" ";//1
	}

size()
返回set内的元素个数

  //1 2 3 4
    cout<<st.size(); //4

clear()
清空st中的所有元素

	st.clear(); 
	cout<<st.size();

empty() 判断是否为空

st.clear(); 
	cout<<st.empty()<<endl;//1 true
st.insert(4);
	st.insert(3);
	st.insert(1);
	st.insert(2);
	//1 2 3 4
	//lower_bound(k) 返回一个迭代器,指向键值不小于k的第一个元素 
	set<int>::iterator it=st.lower_bound(2);//寻找第一个大于等于2的数 
	cout<<*it<<endl;//2
	//upper_bound(k) 返回一个迭代器,指向键值大于k的第一个元素 
	 it=st.upper_bound(2); 
	 cout<<*it<<endl;//3

map


map的定义

map<typename1,typename2> mp;
	
	 map<int,int> mp;
	 map<string,int> mp;
	 map<set<int>,string> mp;

map需要确定映射前类型(键key)和映射后类型(值 value) <>内填写两个类型,其中第一个键的类型,第二个是值的类型,
如果是字符串到整形的映射,必须使用string而不用char数组类型

map容器的内元素的访问
通过下标访问
和访问普通数组一样,例如对一个定义为map<char,int> mp的map来说,就可以直接使用mp[‘c’]的方式来访问它对应的整数,map中的键值是唯一的

	map<char,int> mp;
	mp['c']=1;
	mp['c']=2;//1被覆盖 
	cout<<mp['c']<<endl;//2;

通过迭代器返回

 map<typename1,typename2>::iterator it;

map可以使用it->first来访问键,使用it->second来访问值

map内部是由红黑树实现的
map会以键从小到大的顺序自动排序

insert()
添加一个新的pair到map中

  map<char,int> mp;
  mp['a']=1;
  mp['b']=2;
  mp['c']=3;
  
  
  mp.insert(pair<char,int>('d',4));
  map<char,int>::iterator it;
  	  for(it=mp.begin();it!=mp.end();it++){
    
    
   	 cout<<it->first<<" "<<it->second<<endl; 
   }
   //a 1
  //b 2
  //c 3
  //d 4

pair其实是一个简单的结构体 需要添加#include<utility>
两个元素的结构体

find()
find(key) 返回键值为key的映射迭代器

map<char,int> mp;
  mp['a']=1;
  mp['b']=2;
  mp['c']=3;
  
   map<char,int>::iterator it;
   it=mp.find('a');
   cout<<it->first<<" "<<it->second<<endl; //a 1

查找一个元素是否出现在map中

 map<char,int> mp;
  mp['a']=1;
  mp['b']=2;
  mp['c']=3;
  
  map<char,int>::iterator it;
  it=mp.find('a');
  if(it!=mp.end()){
    
      //存在 
  	cout<<"存在"<<endl; 
  }
  else{
    
    
  	cout<<"不存在"<<endl; 
  }
   it=mp.find('d');
  if(it!=mp.end()){
    
     //不存在 
  	cout<<"存在"<<endl; 
  }
  else{
    
    
  	cout<<"不存在"<<endl; 
  }

count(key)
返回某个键值的数量

  map<char,int> mp;
  mp['a']=1;
  mp['b']=2;
  mp['c']=3;
  mp['c']=4;//会覆盖前面的mp['c']的值 
  cout<<mp.count('c')<<endl; //1

empty()

  map<char,int> mp;
  mp['a']=1;
  mp['b']=2;
  mp['c']=3;
 
   cout<<mp.empty()<<endl;//0

erase()
erase()有两种用法 删除单个元素,删除一个区间内的所有元素
mp.erase(it) it为所需要删除元素的迭代器

map<char,int> mp;
  mp['a']=1;
  mp['b']=2;
  mp['c']=3;
  
   map<char,int>::iterator it;
   it=mp.find('a');

   mp.erase(it);
   for(it=mp.begin();it!=mp.end();it++){
    
    
   	 cout<<it->first<<" "<<it->second<<endl;  //b 2   c 3
   	  
   }

mp.erase(key) key为欲删除的映射的键

map<char,int> mp;
  mp['a']=1;
  mp['b']=2;
  mp['c']=3;

 map<char,int>::iterator it;
   	  mp.erase('b');
   	  for(it=mp.begin();it!=mp.end();it++){
    
    
   	 cout<<it->first<<" "<<it->second<<endl; 
   }

mp.erase 删除一个区间内的所有元素
mp.erase(first,last) 其中first为需要删除的区间的起始迭代器,而last则为所需要删除的区间的末尾迭代器的下一个地址,也即为删除左闭右开的区间

map<char,int> mp;
  mp['a']=1;
  mp['b']=2;
  mp['c']=3;
  mp['d']=4;
  mp['e']=5;
  
  map<char,int>::iterator it;
  it=mp.find('b');
  mp.erase(it,mp.end());
  	  for(it=mp.begin();it!=mp.end();it++){
    
    
   	 cout<<it->first<<" "<<it->second<<endl; //a 1
   }

clear()清空map集合中的所有元素
size()获得map中映射的对数

map<char,int> mp;
  mp['a']=1;
  mp['b']=2;
  mp['c']=3;
  mp['d']=4;
  mp['e']=5;
  
  map<char,int>::iterator it;
    mp.size();
  	  for(it=mp.begin();it!=mp.end();it++){
    
    
   	 cout<<it->first<<" "<<it->second<<endl; 
   }
   mp.clear();
   cout<<mp.size()<<endl;//0

c++11还有一些新特性如 unordered_map,unordered_set还挺好用的大家了解下

algorithm


需要引入#include

max,min,abs
max(x,y)和min(x,y) 求两个值中的最大值,最小值
abs(x)x必须是整形

int a=3,b=4,c=-5;
   
   cout<<max(a,b)<<endl; //4
   cout<<min(a,b)<<endl; //3
   cout<<abs(c)<<endl //5;

swap
swap(x,y)交换两个值

int a=3,b=4,c=-5;
   
   swap(a,b);
   cout<<a<<endl;//4
   cout<<b<<endl;//3

fill()
fill可以把数组或容器中的某一段区间复制为某个值

//清空数组
int ans[100];
  fill(ans,ans+100,0);

  memset(ans,0,sizeof(ans));//memset是按字节赋值的

next_permutation
重点,蓝桥杯经常考,用了这个函数后就不用DFS写全排列了,很方便
我自己测试的好像是必须要自己先把数据排序了才行。。。你们可以自己试一下

int ans[10]={
    
    1,2,3};
   do{
    
    
            printf("%d%d%d\n",ans[0],ans[1],ans[2]);
   }while(next_permutation(ans,ans+3));

lower_bound upper_bound
底层原理应该是二分算法,但是如果我们手写二分第一是比较麻烦,第二是有可能出现边界错误,因此调用这个函数还是很香的啊。。。。
lower_bound (first,last,val)在[first,last)范围内值第一个大于等于val元素
upper_bound(first,last,val)在[first,last)范围内值第一个大于val元素的位置
返回值,如果是数组返回的是该位置的指针,如果是容器,返回该位置的迭代器

这里提一下两个指针相减,就是两个地址之间的距离

int ans[10]={
    
    1,2,2,3,3,4};
    cout<<(lower_bound(ans,ans+10,2)-ans)<<endl; //1
    
    cout<<(upper_bound(ans,ans+10,2)-ans)<<endl; //3

练习题

给你两个集合,计算其并集,即{
    
    A} +{
    
    B}。

注: 中不允许出现重复元素,但是 {
    
    A}{
    
    B}  之间可能存在相同元素。

输入格式

输入数据分为三行,第一行有两个数字 n, m(0<n,m<= 10000),分别表示集合 A 和集合 B 的元素个数。后两行分别表示集合 A 和集合 B。每个元素为不超出int范围的整数,每个元素之间用一个空格隔开。

输出格式

输出一行数据,表示合并后的集合,要求从小到大输出,每个元素之间用一个空格隔开。

样例输入1

1 2
1
2 3
样例输出1

1 2 3
样例输入2

1 2
1
1 2
样例输出2

1 2

解答

#include <bits/stdc++.h>

using namespace std;

int main()
{
    
    

   set<int> st;

int n,m;
cin>>n>>m;
int a;
for(int i=0;i<n;i++)
{
    
    
  cin>>a;
   st.insert(a);

}
for(int i=0;i<m;i++)
{
    
    
   cin>>a;
   st.insert(a);

}

for(set<int>::iterator it=st.begin();it!=st.end();it++)
{
    
    

      cout<<*it<<" ";
}
  return 0;
}

小A快要考托福了,这几天,小A每天早上都起来记英语单词。小B时不时地来考一考蒜头君:小B会询问蒜头君一个单词,如果小A背过这个单词,小A会告诉小B这个单词的意思,不然小A会跟小B说还没有背过。单词是由连续的大写或者小写字母组成。注意单词中字母大小写是等价的。比如"You""you"是一个单词。

输入格式

首先输入一个  表示事件数。接下来 n 行,每行表示一个事件。每个事件输入为一个整数 d 和一个单词 word(单词长度不大于 20),用空格隔开。如果 d=0,表示小A记住了 word 这个单词,如果 d=1,表示这是一个 测试,测试小A是否认识单词 word(小B不会告诉蒜头君这个单词的意思)。事件的输入是按照时间先后顺序输入的。

输出格式

对于小B的每次 测试,如果小A认识这个单词,输出一行"Yes", 否则输出一行"No"。

样例输入1

5
0 we
0 are
1 family
0 Family
1 Family
样例输出1

No
Yes
样例输入2

4
1 jisuanke
0 Jisuanke
0 JISUANKE
1 JiSuanKe
样例输出2

No
Yes

解法1map

#include <bits/stdc++.h>

using namespace std;

int main()
{
    
    
  int n;
  cin>>n;
  map<string,int> mp;
  while(n--)
  {
    
    
    int a;
    string s;
    cin>>a>>s;
    for(int i=0;i<s.length();i++)
    {
    
    
        s[i]=tolower(s[i]);
    }
    if(a==0)
     {
    
    
       mp[s]=1;
     }
     else{
    
    
       if(mp[s]==1)
       {
    
    
         cout<<"Yes"<<endl;
       }
       else{
    
    
         cout<<"No"<<endl;
       }
     }
  }
  return 0;
}

解法二 set

#include <bits/stdc++.h>

using namespace std;

int main()
{
    
    
  int n;
  cin>>n;
  set<string> st;
  while(n--)
  {
    
    
    int a;
    string s;
    cin>>a>>s;
    for(int i=0;i<s.length();i++)
    {
    
    
        s[i]=tolower(s[i]);
    }
    if(a==0)
     {
    
    
       st.insert(s);
     }
     else{
    
    
       if(st.count(s)==1)
       {
    
    
         cout<<"Yes"<<endl;
       }
       else{
    
    
         cout<<"No"<<endl;
       }
     }
  }
  return 0;
}

1064 朋友数 (20)
如果两个整数各位数字的和是一样的,则被称为是“朋友数”,而那个公共的和就是它们的“朋友证号”。例如 12351 就是朋友数,因为 1+2+3 = 5+1 = 6,而 6 就是它们的朋友证号。给定一些整数,要求你统计一下它们中有多少个不同的朋友证号。

输入格式:
输入第一行给出正整数 N。随后一行给出 N 个正整数,数字间以空格分隔。题目保证所有数字小于 104
​​ 。

输出格式:
首先第一行输出给定数字中不同的朋友证号的个数;随后一行按递增顺序输出这些朋友证号,数字间隔一个空格,且行末不得有多余空格。

输入样例:
8
123 899 51 998 27 33 36 12
输出样例:
4
3 6 9 26
#include <bits/stdc++.h>

using namespace std;

int main()
{
    
    
  set<int> st;
  int n,a;
  int sum=0;
  
  cin>>n;
  
  while(n--)
  {
    
    
    cin>>a;
    sum=0;
    while(a)
    {
    
    
      
      sum+=a%10;
      a/=10;
    }
     st.insert(sum);
  }
  int num=0;
  cout<<st.size()<<endl;
  for(set<int>::iterator it=st.begin();it!=st.end();it++)
  {
    
    
    num++;
    
    cout<<*it;
    if(num<st.size())
    {
    
    
      cout<<" ";
    }
  }
  return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_44866153/article/details/112001832