STL经典列题练习

STL经典列题练习

课上练习stack

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	while(1){
		cout << "10进制:";
		cin >> n;
		if(n==-1) break; 
		stack<int> st;
		while(n){
			int a=n%8;
			n/=8;
			st.push(a);
		}
		cout << "8进制:";
		while(!st.empty()){
			cout << st.top();
			st.pop();
		}
		cout << endl;
	}
	return 0;
} 

括号匹配

#include<bits/stdc++.h>
using namespace std;
int main(){
	string s;
	cin >> s;
	stack<char> st;
	int f=1;
	for(int i=0;i<s.size();i++){
		if(s[i]=='('||s[i]=='[') st.push(s[i]);
		else{
			if(st.empty()) f=0;
			else if((s[i]==')'&&st.top()!='(')||(s[i]==']'&&st.top()!='[')) f=0;
			else if((s[i]==')'&&st.top()=='(')||(s[i]==']'&&st.top()=='[')){
				st.pop();
			}
		}
	}
	
	if(!st.empty()) f=0;
	
	cout << f << endl;
	return 0;
}

F - 士兵队列训练问题 HDU - 1276

vector模拟问题

#include<bits/stdc++.h>
using namespace std;
int main(){
	int t;
	cin >> t;
	while(t--){
		vector<int> v;
		int n;
		cin >> n;
		for(int i=1;i<=n;i++) v.push_back(i);
		int add=1;
		while(v.size()>3){
			
			if(add==1){
				for(int i=1;i<v.size();i++){
					v.erase(v.begin()+i,v.begin()+i+1);
				}
				add=2;
			}
			else{
				for(int i=2;i<v.size();i+=2){
					v.erase(v.begin()+i,v.begin()+i+1);
				}
				add=1;
			}
			
		}
		
		for(int i=0;i<v.size();i++){
			if(!i) cout << v[i];
			else cout << ' ' << v[i];
		}
		cout << endl;	 
	}
	return 0;
}

G - 产生冠军 HDU - 2094

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	while(cin >> n&&n){
		set<string> s1,s2;
		string a,b;
		while(n--){
			cin >> a >> b;
			s1.insert(a);
			s1.insert(b);
			s2.insert(b);	
		}
		if(s1.size()-s2.size()==1) cout << "Yes" << endl;
		else cout << "No" << endl;

	}
	return 0;
} 
/*
这题用set就特别简单,set1表示所有人的集合,set2表示所有失败者的集合,那只要set1比set2大1就表示有一人是胜利者;
*/

vjudge地址

第一题:A - Shopping HDU - 2648

题目大意:求memory店每天的排名

分析:map题目

重点:map和迭代器的使用

易错:多组输入

#include<bits/stdc++.h>
using namespace std;
int main(){//注意多组数据输入 
	int n;
	while(cin >> n){
		map<string,int> shop;//运用map ,一种映射 
		map<string,int>::iterator it;//迭代器 
		for(int i=1;i<=n;i++){
			string s;
			cin >> s;
			shop[s]=0;//可有可无,默认是0 
		}
		
		int day;
		cin >> day;
		while(day--){
			int a;
			string s;
			for(int i=1;i<=n;i++){
				cin >> a >> s;
				shop[s]+=a;//在迭代器中加入增加的值	
			} 
			
			//开始运用迭代器循环找出memory第几名
			int rank=1;//记录排名 
			for(it=shop.begin();it!=shop.end();it++){
				if(it->second>shop["memory"]) rank++; 
			} 
			cout << rank << endl;
		} 
	}
	return 0;
}

B - Ignatius and the Princess II HDU - 1027

next_permutation()函数

分析:可以用dfs做,会有点麻烦,在stl中有个更简单的函数,next_permutation

#include<iostream>//全排列多种办法
#include<algorithm>
using namespace std;
int a[1005];
int main(){
	int n,m;
	while(cin >> n >> m){
		for(int i=1;i<=n;i++) a[i]=i;
		int b=1;
		do{
			if(b==m) break;
			b++;
		}while(next_permutation(a+1,a+n+1));//模板
		
		for(int i=1;i<=n;i++){
			if(i==1) cout << a[i];
			else cout << ' ' <<a[i]; 
		}
		cout << '\n';
	}
	return 0;
} 

C - 排列2 HDU - 1716

这一题一看就和B题很相似,首先理解next_permutation能实现什么样的功能,首先得对数组排序,返回存在的下一个排序

在这里插入图片描述

代码

易错:就是题目里给你空行,不注意容易出现Presentation Error的错误

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int main()
{
    int a[4],ok=0;
    cin>>a[0]>>a[1]>>a[2]>>a[3];
    while(1){
        if(a[0]+a[1]+a[2]+a[3]==0) break;
        sort(a,a+4);//排序
        int k=a[0];
        if(a[0]!=0) cout<<a[0]<<a[1]<<a[2]<<a[3];
        while(next_permutation(a,a+4)){
            if(a[0]==k&&a[0]!=0) cout<<" "<<a[0]<<a[1]<<a[2]<<a[3];
            else{
                if(a[0]!=0){
                    if(k!=0) cout<<endl;//换行
                    cout<<a[0]<<a[1]<<a[2]<<a[3];
                }
                k=a[0];
            }
        }
        cout<<endl;
        cin>>a[0]>>a[1]>>a[2]>>a[3];//仅仅有下次不退出才换行
        if(a[0]+a[1]+a[2]+a[3]!=0) cout<<endl;
    }
    return 0;
}

D - Where is the Marble? UVA - 10474

题目大意:输入n个整数,代表大理石编号;再输入q个数(编号),问是否有这个编号的大理石,位置在哪里?

了解 lowwer_bound()与upper_bound()

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
int cnt[100000];
int main(){
	int n,m,count=1;//标记case 
	while(cin >> n >> m){
		if(!n&&!m) break;
		printf("CASE# %d:\n",count++);
		for(int i=1;i<=n;i++) cin >> cnt[i];

		sort(cnt+1,cnt+n+1);//关键排序 

		while(m--){
			int a;
			cin >> a;
			int b=lower_bound(cnt+1,cnt+n+1,a)-cnt;//lowwer_bound的使用 
			if(cnt[b]==a) printf("%d found at %d\n",a,b);
			else printf("%d not found\n",a);
		}		 
	}
	return 0;
}

E - The Blocks Problem UVA - 101

题目大意: 先理解给出的四个移动方式:

move a onto b:把木块a、b上的木块放回各自的原位,再把a放到b上;
move a over b:把a上的木块放回各自的原位,再把a发到含b的堆上;

pile a onto b:把b上的木块放回各自的原位,再把a连同a上的木块移到b上;

pile a over b:把a连同a上木块移到含b的堆上。

然后根据条件来移动即可。

解题思路

如果把每个情况都写出来肯定很麻烦,所以首先先找出他们的共同点然后来写出算法,这样就会简单很多,如

找到某木块
将某木块上的木块放回原位
将某木块及其上面木块移动到另一个木块上

vector 模拟题

#include<string>
#include<vector>
#include<iostream>
    using namespace std;
    int n;
    vector<int> num[24];
    void find(int a, int & i, int &j )
    {
        for (i = 0; i < n; i++)
            for (j = 0; j< num[i].size(); j++)
                if (num[i][j] == a) return;
    }
    void over(int j, int h)
    {
        for (int i = h + 1; i < num[j].size(); i++)
        {
            int b = num[j][i];
            num[b].push_back(b);
        }
        num[j].resize(h + 1);
    }
    void renew(int p, int h, int g )
    {
        for (int i = h; i < num[p].size(); i++)
            num[g].push_back(num[p][i]);
        num[p].resize(h);
    }
    int main()
    {
        int a, b;
        cin >> n;
        string s1, s2;
        for (int i = 0; i < n; i++)
            num[i].push_back(i);
        while (cin >> s1)
        {
            if (s1 == "quit")
            {
                for (int i = 0; i < n; i++)
                {
                    cout << i<<":";
                    for (int j = 0; j < num[i].size(); j++)
                        cout <<" "<<num[i][j];
                    cout << endl;
                }
                break;
            }  
            cin >> a >> s2 >> b;
            int q, w, e, r;
            find(a, q, e);
            find(b, w, r);
            if (q == w)
                continue;
            if (s2 == "onto")
                over(w, r);
            if (s1 == "move")
                over(q, e);
            renew(q, e, w);
        }
 
        system("pause");
        return 0;
    }
  

F - Andy’s First Dictionary UVA - 10815

题意:

给你一段文字,把所有的单词挑出来,然后转小写排序打印、
打印的时候不能打印重复的,因此,在打印的时候一个判断就好‘

解析

集合set的用法 :​​​​​​​

   1.set是数学上的一个集合,每个元素最多只出现一次,使得省略去重操作。

   2.由于string已经定义了“小于”符号,使得存入set中的元素已经从小到大排好序

  ,所以直接用set保存单词集合。

tolower()函数

#include<bits/stdc++.h>
using namespace std;
int main(){
	set<string> se;
	set<string>::iterator it; 
	string s;
	while(cin >> s){//输入字符串 
		int pos=0,len=s.size();
		while(1){//知道EOF结束 
			string ss;
			while(isalpha(s[pos])){//取出一个完整的字符串 
				ss+=s[pos];
				pos++;
			}
			
			for(int i=0;i<ss.size();i++) ss[i]=tolower(ss[i]);//转小写 

			
			if(ss!="") se.insert(ss);//如果ss有值,便存入set 
			
			if(pos>=len) break;
			pos++;	
		}	
	}
	
	for(it=se.begin();it!=se.end();it++){//迭代器输出 
		cout << *it << endl;
	}
	
		
	return 0;
}

数据流写法更简便,原理相同,数据流取出单词方式不同


#include<set>
#include<iostream>
#include<string>
#include<sstream>
using namespace std;
set<string> dict;  //string 集合 
int main()
{
	string s,buf;
	while(cin>>s)
	{
		for(int i=0;i<s.length();i++)
		{
			if(isalpha(s[i]))
			   s[i]=tolower(s[i]);
			//tolower将大写字母转为小写 
			else s[i]=' '; 
		}
		stringstream ss(s);
		
		while(ss>>buf)
		   dict.insert(buf);		
	}
	for(set<string>::iterator it=dict.begin();it!=dict.end();it++)
	   cout<<*it<<endl;
	   return 0;	
}

G - Ananagrams UVA - 156

对比给出的字符串是否存在无论怎么变换字母位置都不会重复的字符串,将他按字典序输出

思路:先把单词从字符串中提取出来存入vector中,然后复制一份把大写改为小写,并且对每个单词内字母排序,然后对比vector里面的单词看出现的次数,看是不是只出现一次还是出现多次。。

#include<bits/stdc++.h>
using namespace std;
map<string,int> m; 
map<string,int>::iterator it;

bool cmp1(string s1,string s2){//对字符串数组排序 
	return s1<s2;
}

bool cmp2(char x,char y){//对字符串排序 
	return x<y;
}

string tran(string s){//将字符串转化为排完序的字符串 
	for(int i=0;i<s.size();i++){
			s[i]=tolower(s[i]);
		}
	sort(s.begin(),s.end(),cmp2);
	return s;
}

int main(){
	string s;
	vector<string> v;//储存原字符 
	while(cin >> s){
		if(s=="#") break;
		v.push_back(s);
		
		string ss=tran(s);
		m[ss]++;
//		cout << ss << endl;
	}
	
	sort(v.begin(),v.end(),cmp1);排序 
	
	for(int i=0;i<v.size();i++){
		if(m[tran(v[i])]==1) cout << v[i] << endl;
	}
	
	return 0;
} 

H - The SetStack Computer UVA - 12096

难,我也不会,尽力了

I - Team Queue UVA - 540

题解:题意就是一个队列相同组的可以插队,插到相同队员的后面,思路是弄多个队列,用一个队列来确定队编号的序列,一个数组判断当前队是否还有队员,没有队员标记为空;

他人解说

J - Ugly Numbers UVA - 136

题目大意:丑数是指不能被2,3,5以外的其他素数整除的数。求第1500个丑数。

思路:最小的丑数是1,对任意丑数x,2x,3x,5x也是丑数。用优先 队列保存已经生成的丑数,再依次取出最小的丑数生成三个新的丑数就好了,注意生成丑数的来源多种,需要判断新生成的丑数是否已存在。

需要用到set来去重,也需要用到优先队列去将思路中新生成的丑数排序。

题目解析

优先队列解析

#include<iostream>
#include<vector>
#include<queue>
#include<set>
using namespace std;
typedef long long ll;
const int coeff[3] = { 2, 3, 5 };
int main()
{
	priority_queue <ll,vector<ll>,greater<ll> > pq;//自定义排序,默认是从大到小 
	set<ll>s;
	pq.push(1);
	s.insert(1);
	for (int i = 1;; i++)
	{ 
		ll x = pq.top(); pq.pop();
		if (i == 1500)
		{
			cout << "The 1500'th ugly number is " << x << "." << endl;
			break;
		}
		for (int j = 0; j < 3; j++)
		{
			ll x2 = x*coeff[j];
			if (!s.count(x2))
			{
				s.insert(x2);
				pq.push(x2);
			}
		}
	}
	return 0;
}

L - 单词数 HDU - 2072

思路:set去重

输入方法新思路,运用stringstream,可以直接将带空格的字符串隔开,并一一输出剩余的字符串!

Stringstream运用

#include<bits/stdc++.h>
using namespace std;
int main(){
	string s;
	set<string> se;
	set<string>::iterator it;
	while(getline(cin,s)&&s!="#"){ 
		stringstream ss;
		ss<<s;
		string p; 
		while(ss>>p){
			se.insert(p);
		}
		cout << se.size() << endl;
		se.clear();	
	}
/*	
	for(it=se.begin();it!=se.end();it++){
		cout << *it << endl;
	}
*/
	
	return 0;
} 
  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: STL是指C++标准模板库(Standard Template Library),包含了大量可重用的算法和数据结构。在C++编程中,STL被广泛使用,因为它具有高效、可重用、通用等优点,能够提高程序的开发效率和质量。 STL语言编程题经典100例是一本专门针对STL的编程练习题集。这个题集包含了100个编程题目,涵盖了STL中常用的算法和数据结构,包括容器、迭代器、算法等,是STL编程学习和巩固的绝佳材料。 这个题集的下载链接可能会有多个,一般可以在C++编程网站或者相关社区论坛里找到。在使用这个题集时,我们可以按照题目要求完成相应的代码实现,再进行测试,看看最终的输出结果是否符合预期。 通过练习这些STL编程题,我们可以更好地理解STL的底层原理和使用方法,例如如何遍历STL容器,并且能够灵活运用STL算法,提高程序的运行效率以及可读性。因此,STL语言编程题经典100例是C++编程爱好者必备的学习资料之一,能够让我们更好地掌握STL编程技术,从而能够在实际编程中运用到STL技术,提升自己的编程能力。 ### 回答2: STLStandard Template Library,标准模板库)是C++编程中的一种开源库,包含许多常用的数据结构和算法,提高了C++程序的开发效率。在学习STL语言编程的过程中,经典题目的练习非常重要。而“STL语言编程题经典100例”是一本很好的参考书籍,收录了100个STL语言编程的经典题目。 这本书中的编程题目设计不同的难度级别,让读者可以从易到难、由浅入深地学习STL语言编程。这些题目大多数都是实际应用场景中的问题,例如排序、查找、统计、计算等,有很强的实用性。通过解题的过程,读者可以熟悉和掌握STL容器、迭代器、算法等模板库的使用,提高自己的编程水平。 此外,这本书也对每个编程题目都给出了详细的解答和分析,辅助读者理解和掌握算法思想,同时还提供了多种解法,并指出每种解法的优缺点。这样读者可以选出最优的解法,提高程序的效率和可读性。 总之,“STL语言编程题经典100例”是一本很好的STL语言编程的实践指南,值得每个STL语言编程爱好者阅读和学习。 ### 回答3: STL语言编程题经典100例是一份非常有用的编程题集,该题集收集了100个经典STL语言编程题,可以帮助学生深入理解STL语言的特点和使用方法。 该题集不仅包含了基础的STL容器和算法的应用,还涵盖了STL的高级应用,如STL的自定义容器和算法。此外,该题集还提供了详细的题目分析和解答,使学生能够深刻理解STL编程的思路和方法。 该题集的下载方式也很简单,只需要在网上搜索“STL语言编程题经典100例”即可找到相应的下载链接。同时,该题集的大小也比较适中,不会占用过多的存储空间,方便学生进行下载和使用。 总之,STL语言编程题经典100例是一份非常有价值的编程题集,可以帮助学生深入了解STL语言的使用方法和特点,提升编程能力和技巧。推荐广大STL爱好者进行下载和使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值