算法竞赛入门经典-STL数据结构的使用

1.洗牌在生活中十分常见,现在需要写一个程序模拟洗牌的过程。 现在需要洗2n张牌,从上到下依次是第1张,第2张,第3张一直到第2n张。首先,我们把这2n张牌分成两堆,左手拿着第1张到第n张(上半堆),右手拿着第n+1张到第2n张(下半堆)。接着就开始洗牌的过程,先放下右手的最后一张牌,再放下左手的最后一张牌,接着放下右手的倒数第二张牌,再放下左手的倒数第二张牌,直到最后放下左手的第一张牌。接着把牌合并起来就可以了。 例如有6张牌,最开始牌的序列是1,2,3,4,5,6。首先分成两组,左手拿着1,2,3;右手拿着4,5,6。在洗牌过程中按顺序放下了6,3,5,2,4,1。把这六张牌再次合成一组牌之后,我们按照从上往下的顺序看这组牌,就变成了序列1,4,2,5,3,6。 现在给出一个原始牌组,请输出这副牌洗牌k次之后从上往下的序列。


思路使用栈(这里没有用到STL 容器)

#include<iostream>
#include<string.h>
#include<ctype.h>
using namespace std;
 
int stack[200+10];
int stack1[100+10];
int stack2[100+10];
int length=0;
int length1=0;
int length2=0;
int main()
{
    int T;
    int n,k;
     
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&k);
        for(int i=0;i<2*n;i++)
        {scanf("%d",&stack[2*n-1-i]);}
        length=2*n;
 
        while(k--)
 
        {//分成两堆
            length1=0;
            length2=0;
            for(int i=0;i<n;i++)
            stack1[length1++]=stack[--length];//左手
            for(int i=n;i<2*n;i++)
            stack2[length2++]=stack[--length];//右手
        //洗牌
            length=0;
            while(length1>0 && length2>0)
            {
                stack[length++]=stack2[--length2];//长度先减一,再出栈
                stack[length++]=stack1[--length1];
            }
            //和牌
 
        }
        //输出栈(自顶向下)
            while(length>1)
            {
                printf("%d ",stack[--length]);
            }
            printf("%d\n",stack[--length]);
    }
    //system("pause");
    return 0;
}
2. 小明同学把1到n这n个数字按照一定的顺序放入了一个队列Q中。现在他对队列Q执行了如下程序:

while(!Q.empty())              //队列不空,执行循环

{

    int x=Q.front();            //取出当前队头的值x

    Q.pop();                 //弹出当前队头

    Q.push(x);               //把x放入队尾

    x = Q.front();              //取出这时候队头的值

    printf("%d\n",x);          //输出x

    Q.pop();                 //弹出这时候的队头

}

做取出队头的值操作的时候,并不弹出当前队头。
小明同学发现,这段程序恰好按顺序输出了1,2,3,...,n。现在小明想让你构造出原始的队列,你能做到吗?

解题思路:把该过程逆向(使用双端队列实现)

#include<iostream>
#include<string.h>
#include<ctype.h>
using namespace std;
 
#include<deque>
int main()
{
    int T;
    int n;
    scanf("%d",&T);
    while(T--)
    {
        deque<int> q;
        scanf("%d",&n);
        while(n)
        {
            q.push_front(n--);
            int t=q.back();
            q.push_front(t);
            q.pop_back();
        }
 
        //从队头到队尾,依次输出
        while(q.size()>1)
        {cout<<q.front()<<" ";
        q.pop_front();
        }
        cout<<q.front()<<endl;
    }
    //system("pause");
    return 0;
}

3. 已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号1开始报数,数到k的那个人出列;他的下一个人又从1开始报数,数到k的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。 
例如n=10,k=3时,输出的出列顺序是3,6,9,2,7,1,8,5,10,4。

解题思路,典型的使用链表实现。STL中链表实现方式有多种,这里使用vector

#include<iostream>
#include<vector>
using namespace std;

int main()
{
    vector<int> a;              //定义向量对象a
    int n,k,x=0;
    cout<<"请输入总人数n和出环位置k:"<<endl;
    cin>>n>>k;
    for(int i=0; i<n; i++)
    {
        a.push_back(i+1);   //初始化向量对象a,依次将i+1插入尾部
    }
    while(a.size())             //当向量中元素个数不为0
    {
        x = (x+k-1) % a.size();     //计算出环位置
        cout<<a[x]<<" ";
        a.erase(a.begin()+x);       //在向量中删除此元素
    }
	system("pause");
    return 0;
}


看到这里,读者应该能发现,在程序设计过程中使用现成的数据结构实现,能减少程序设计的麻烦,算法思路更加明确

这里做一个简单的总结,总结程序设计构成中常用的STL

1)。栈 stack

  1. #include <stack>  //引入栈
  2. 在STL中栈一共就5个常用操作函数(top()、push()、pop()、 size()、empty() ),很好记的。
定义一个stack的变量     stack<Type> s   //例如  stack <int> Q,q,、、

入栈,如例:s.push(x);

出栈,如例:s.pop();注意,出栈操作只是删除栈顶元素,并不返回该元素。

访问栈顶,如例:s.top()

判断栈空,如例:s.empty(),当栈空时,返回true。

访问栈中的元素个数,如例:s.size()


2)队列

定义一个queue的变量     queue<Type> M   //例如  queue <int> Q,q,、、
查看是否为空范例        M.empty()    是的话返回1,不是返回0;
从已有元素后面增加元素   M.push()
输出现有元素的个数      M.size()
显示第一个元素          M.front()
显示最后一个元素        M.back()
清除第一个元素          M.pop()


3)双端队列

使用deque容器之前必须加上<deque>头文件:#include<deuqe>;

deque<Elem> c 创建一个空的deque;

c.front()返回c容器的第一个元素

c.back()返回c容器的最后一个元素

c.size()返回c容器中实际拥有的元素个数

c.push_back(num)在末尾位置插入元素

c.pop_back()删除末尾位置的元素

c.push_front(num)在开头位置插入元素

c.pop_front()删除开头位置的元素

另外常用的还有:

c.insert(pos,num)在pos位置插入元素num

c.erase(pos)删除pos位置的元素

下面看一道经典的约瑟夫环的题

问题描述: 
已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号1开始报数,数到k的那个人出列;他的下一个人又从1开始报数,数到k的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。 
例如n=10,k=3时,输出的出列顺序是3,6,9,2,7,1,8,5,10,4。

#include<iostream>
#include<deque>
using namespace std;

int main()
{
    deque<int> a;              //定义向量对象a
    int n,k,x=0;
    cout<<"请输入总人数n和出环位置k:"<<endl;
    cin>>n>>k;
    for(int i=0; i<n; i++)
    {
        a.push_back(i+1);   //初始化向量对象a,依次将i+1插入尾部
    }
    while(a.size())             //当向量中元素个数不为0
    {
        x = (x+k-1) % a.size();     //计算出环位置
        cout<<a[x]<<" ";
        a.erase(a.begin()+x);       //在向量中删除此元素
    }
	system("pause");
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: C++ STL(Standard Template Library)是一种功能强大的库,提供了一套丰富的数据结构算法实现。在余文溪的《C++ STL数据结构算法实现》这本PDF书中,详细介绍了STL的各种数据结构算法的实现。 首先,STL提供了几种基本的数据结构,例如vector(动态数组)、list(双向链表)、deque(双端队列)、set(集合)、map(映射)等。这些数据结构STL中都有相应的实现和操作函数,能够方便地进行插入、删除、查找等操作。 此外,STL还提供了一些算法,包括排序、查找、遍历等等。这些算法可以应用于STL的各种数据结构上,提供了一种高效且易用的方式来处理数据。例如,STL中提供了排序算法sort,可以对vector、list等容器进行排序操作;还有查找算法find,可以在set、map等容器中进行查找操作。 在《C++ STL数据结构算法实现》中,余文溪详细阐述了STL的实现原理和内部细节,帮助读者深入理解STL的工作原理。通过学习这本书,读者可以了解到STL设计思想、使用方法和性能特点,从而能够更好地应用STL解决问题。 总而言之,STL提供了一套强大的数据结构算法实现,通过余文溪的《C++ STL数据结构算法实现》这本PDF书,读者可以深入了解STL使用方法和内部原理,提升编程能力。 ### 回答2: C++ STL(Standard Template Library,标准模板库)是C++标准库的一部分,为我们提供了丰富的数据结构算法实现。余文溪编写的《C++ STL 数据结构算法实现》PDF是一本介绍STL经典教材。 STL包含了很多常用的数据结构,例如向量(vector)、链表(list)、集合(set)和映射(map)等。这些数据结构都已经被封装好,通过STL可以方便地进行插入、删除、查找等操作。同时,STL还提供了强大的算法库,例如排序、查找、拷贝和逆序等。使用STL数据结构算法,可以极大地提高我们的编程效率。 《C++ STL 数据结构算法实现》是一本很好的学习STL的教材。其中,余文溪详细地介绍了STL的各种数据结构算法,通过代码示例和讲解,深入浅出地帮助读者理解STL使用方法。这本教材适合初学者和有一定基础的读者阅读,对于了解STL的基本概念和使用方法非常有帮助。 在读完《C++ STL 数据结构算法实现》后,读者将能够熟练使用STL提供的数据结构算法,加快自己的编程效率。同时,通过掌握STL使用,读者也能更好地理解C++标准库的设计思想和使用方法,提升自己的编程水平。 总之,《C++ STL 数据结构算法实现》是值得一读的一本STL教材,能够帮助我们更好地学习和应用STL,提高我们的编程效率和水平。 ### 回答3: STL(Standard Template Library)是C++的标准库之一,提供了丰富的数据结构算法实现。而余文溪编写的《C++ STL数据结构算法实现》这本PDF书籍主要介绍了STL使用方法和内部实现原理。 该书首先介绍了STL的基本概念和使用方法,包括迭代器、容器、算法等方面的内容。通过对各种容器(如vector、list、set、map等)和算法(如排序、查找、合并等)的讲解,读者可以了解到STL的强大功能和高效性。 此外,余文溪在书中也深入探讨了STL的内部实现原理。他通过剖析STL的源代码,详细解释了其中的数据结构算法实现细节。这对于希望深入理解STL底层机制的读者来说,是非常有价值的。 《C++ STL数据结构算法实现》这本书的另一个特点是提供了大量的示例代码和实战练习。通过实际编写代码和完成练习,读者可以巩固所学知识,并提升自己的编程能力。 总之,余文溪的这本PDF书籍对于想要掌握STL使用方法和底层实现原理的C++程序员来说,是一本非常实用的工具书。无论是初学者还是有一定经验的开发者,都可以从中获得很多有价值的知识和技能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值