队列之卡片游戏

桌上有叠牌,从第一张牌(即位于顶面的牌)开始从上往下依次编号为1~n。当至少还剩两张牌时进行以下操作:把第一张牌扔掉,然后把新的第一张放一整叠牌的最后。输入n,输出每次扔掉的牌,以及最后剩下的牌。

样例输入:7

样例输出:1 3 5 74 2 6

【分析】

本题中牌像在排队。每次从排头拿到两个,其中第二个再次排到尾部。这种数据结构称为队列。在数据结构称为FIFO(First in First out,先进先出)表。

用一个数组queue来实现这个队列,可设两个指针front和rear。

完整的程序如下:

#include<stdio.h>

constint MAXN = 50;

int queue[MAXN];

intmain() {

  int n,front, rear;

  scanf("%d", &n);

  for(int i = 0; i < n; i++) queue[i] = i+1;  //初始化队列

  front = 0;                                  //队首元素的位置

  rear = n;                                   //队尾元素的后一个位置

  while(front< rear) {                      //当队列非空

    printf("%d ", queue[front++]);            //输出并抛弃队首元素

    queue[rear++]= queue[front++];           //队首元素转移到队尾

  }

  return 0;

}


 

注意:上面的程序有bug。如果在最后把rear的值打印出来,rear比n大。即在程序运行的后期,queue[rear++]=queue[front++]读写了非法内存。也可以采取将数组空间开大些,或采取一种称为循环队列的技术,重用已出队元素占用的空间。

C++提供了一种更加简单的处理方式——STL队列。下面是代码:

#include<cstdio>

#include <queue>

usingnamespace std;

 

queue<int> q;

intmain() {

  int n, front, rear;

  scanf("%d", &n);

  for(int i = 0; i < n; i++)  q.push(i+1);  //初始化队列

  while(!q.empty()){                       //当队列非空

    printf("%d ", q.front());               //打印队首元素

    q.pop();                                //抛弃队首元素

    q.push(q.front());                      //把队首元素加入队尾

    q.pop();                               //抛弃队首元素

  }

  return 0;

}


 

上面的程序的可读性大大增强了,体现在“queue”、“front”见名知义的命名,使用了C++ STL。除此之外,上面的代码还有两个附加的好处。首先,不需要事先知道n的大小;其次,可以少用两个变量front和rear。减少魔术数(magicnumber)和变量个数都是提高代码可读性、减少错误可能性的重要手段。

说明:(1)在ACM竞赛中,需要用到数组、字符串、队列、堆栈、链表、平衡二叉检索树等数据结构和排序、搜索等算法,以提高程序的时间、空间运行效率,这些数据结构,如果需要手工来编写,那是相当麻烦的事情。

(2)ANSI C++中包含了一个C++ STL(Standard Template Library),即C++标准模板库,又称为C++泛型库,它在std命名空间中定义了常用的数据结构和算法,使用起来十分方便。

(3)C++ STL组件

STL组件三种类型的组件:容器、迭代器和算法,它们都支持泛型程序设计标准。

容器主要有两类:顺序容器和关联容器。顺序容器(vector、list、queue、string等)一系列元素的有序集合。关联容器(set、multiset、map和mulimap)包含查找元素的键值。

迭代器的作用是遍历容器。

STL算法库包含四类算法:排序算法、不可变序算法、变序性算法和数值算法。

(4)queue队列容器

queue队列容器是一个先进先出(First In First Out,FIFO)线性存储表,元素的插入只能在队尾、元素的删除只能在队首。

使用queue需要声明头文件包含语句“#include <queue>”,queue文件在C:Program

FilesMicrosoft Visual StudioVC98Include文件夹里。

queue队列的操作有入队push()(即插入元素)、出队pop()(即删除元素)、读取队首元素front()、读取队尾元素back()、判断队列是否为空empty()和队列当前元素的数目size()。

下面给出一个程序来说明queue队列的使用方法。

#include<iostream>

#include<queue>

usingnamespace std;

 

intmain() {

   //定义队列,元素类型是整型

  queue<int>q;

  //入队,即插入元素

  q.push(1);

  q.push(2);

  q.push(3);

  q.push(9);

  //返回队列元素数量

  cout<<q.size()<<endl;

  //队列是否为空,是空,则返回逻辑真,否则返回逻辑假

  cout<<q.empty()<<endl;

  //读取队首元素

  cout<<q.front()<<endl;

  //读取队尾元素

  cout<<q.back()<<endl;

  //所有元素出列(删除所有元素)

  while(q.empty()!=true){

    cout<<q.front()<<"";

    //队首元素出队(删除队首元素)

    q.pop();

   }

  //回车换行

  cout<<endl;

  return 0;

}


 

运行结果:

4

0

1

9

1  2 3  9

原文地址:https://www.cnblogs.com/riskyer/p/3221907.html