STL--队列


Given is an ordered deck of n cards numbered 1to n with card 1 at the top and card n at thebottom. The following operation is performed aslong as there are at least two cards in the deck:

        Throw away the top card and move

        the card that is now on the top of the

        deck to the bottom of the deck.

  Your task is to find the sequence of discardedcards and the last, remaining card.


Input

Each line of input (except the last) contains anumber n ≤ 50. The last line contains ‘0’ andthis line should not be processed.

Output

For each number from the input produce twolines of output. The first line presents the sequenceof discarded cards, the second line reportsthe last remaining card. No line will haveleading or trailing spaces. See the sample for theexpected format.

Sample Input

7

19

10

6

0

Sample Output

Discarded cards: 1, 3, 5, 7, 4, 2

Remaining card: 6

Discarded cards: 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 4, 8, 12, 16, 2, 10, 18, 14

Remaining card: 6

Discarded cards: 1, 3, 5, 7, 9, 2, 6, 10, 8

Remaining card: 4

Discarded cards: 1, 3, 5, 2, 6

Remaining card: 4


问题链接UVA10935 Throwing cards away I

问题简述:(略)

问题分析:(略)

程序说明

  这是一个模拟问题,直接使用map来模拟即可。

  然而,效率更高的做法是,自己构建一个循环队列来实现模拟。需要注意的是,那个队列的存储单元至少要比最大值大1,否则会出现下标异常。

题记:(略)

参考链接:(略)


AC的C语言程序如下:

(循环队列)

/* UVA10935 Throwing cards away I */  
  
#include <stdio.h>  
  
#define N (50 + 1)  
int cq[N], headcq, tailcq;  //cq[]是循环队列
  
void pushcq(int v)  
{  
    cq[tailcq++] = v;  
    tailcq %= N;  //模除的作用是循环,
}  //入队
  
void popcq()  
{  
    headcq++;  
    headcq %= N;  
}  //出队
  
int frontcq()  
{  
    return cq[headcq];  
}  
  
int sizecq()  
{  
    return (tailcq + N - headcq) % N;  
}  
  
void initcq()  
{  
    headcq = tailcq = 0;  //初始化队列
}  
  
int main(void)  
{  
    int n, i;  
  
    while(~scanf("%d", &n) && n) {  
        initcq();  
  
        for(i=1; i<=n; i++)  
            pushcq(i);  
  
        printf("Discarded cards:");  
  
        int nofirst = 0;  
        while(sizecq() >= 2) {  
            if(nofirst)  
                printf(",");  
            nofirst = 1;  
  
            printf(" %d", frontcq());  
  
            popcq();  
            pushcq(frontcq());  
            popcq();  
        }  
        printf("\nRemaining card: %d\n", frontcq());  
    }  
  
    return 0;  
}  

### 实现自定义双端队列 为了实现一个不依赖于标准模板库(STL)的双端队列(DS队列),可以创建一个新的类`Deque`来管理内部存储的数据。该数据结构应支持两端高效地插入和移除元素,同时也允许快速访问任意位置上的项目。 #### 类设计概述 - 使用动态分配内存的方式处理底层容器。 - 维护两个指针分别指向头部(head)和尾部(tail)的位置。 - 当执行push操作时,在相应的一侧增加新节点;pop则减少对应一侧的节点数量。 - 支持随机访问功能以便获取指定索引处的内容。 下面是具体的C++代码示例: ```cpp #include <iostream> using namespace std; class Deque { private: int* data; size_t head, tail, capacity, count; public: // 构造函数初始化成员变量并预留一定空间给data数组 Deque(size_t initialCapacity = 8): data(new int[initialCapacity]), head(0), tail(initialCapacity - 1), capacity(initialCapacity), count(0) {} ~Deque() { delete[] data; } void push_front(int value); void push_back(int value); bool empty() const { return count == 0; } size_t size() const { return count; } int& front(); int& back(); void pop_front(); void pop_back(); protected: void resize(); // 扩展容量的方法 }; void Deque::resize(){ if(count >= capacity){ auto newCap = max(capacity * 2u, static_cast<size_t>(1)); auto newData = new int[newCap]; for(auto i=0;i<count;++i){ newData[i] = data[(head+i)%capacity]; } delete [] data; data = newData; head = 0; tail = count ? (count - 1):(newCap - 1); capacity = newCap; } } // 插入到前面 void Deque::push_front(int value){ if(++tail == capacity) tail %= capacity; data[tail] = value; ++count; resize(); } // 添加到最后面 void Deque::push_back(int value){ if(--head == -1) head += capacity; data[head] = value; ++count; resize(); } // 获取最前边的元素 int& Deque::front(){ return data[(head+1)%capacity]; } // 获取最后面的元素 int& Deque::back(){ return data[tail]; } // 移除最前端项 void Deque::pop_front(){ if(!empty()){ --count; if(++tail == capacity) tail -= capacity; } } // 删除最后一个元素 void Deque::pop_back(){ if (!empty()) { --count; if (--head == -1) head += capacity; } } ``` 此版本实现了基本的功能需求,并且包含了自动调整大小的能力以适应更多的元素加入[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值