算法设计与分析 G : 排队援救

 描述:

突发重大灾难,n个人陷入困境,有一个救援点需要人们排队准备接受救援,假设每个人有一个名望值,进队规则如下:

  • 第一个人直接进队;
  • 当队里已经有人时,新来的人发现队尾的人的名望值比自己大或者相等,他会选择离开去其他救援点;
  • 队伍最多5人,如果一个人要进队时,发现队伍已满,而且他的名望值比队尾的人大,他会选择把队首的人挤掉而继续排在队尾。

问最后得到救援的人分别是谁。

输入

单组数据。

第一行为n(1 ≤ n ≤ 100),n为正整数。

第二行为n个人的名望值,第i个去排队的人的名望值为ai (1 ≤ ai ≤ 232 - 1),且为正整数。

输出

按顺序输出最后得到救援的人的号码,一个人号码是多少即为他是第几个去排队的。

输入样例

1 3 5 7 9 11

输出样例

2 3 4 5 6

 题目分析:

该题需要用到队列,根据题目条件进行相关的分类即可

当一个新元素想要进入队列时,分为三种情况

①队列为空时,直接入队

②队列未满时(大小 <5),且新元素的大小 >队尾元素大小 ,新元素入队

③队列已满时,且新元素的大小 >队尾元素大小,队头元素出队,新元素入队

#include<iostream>
#include<string>
#include<queue>
using namespace std;
struct people
{
    int value;//声望值
    int number;//号码
};
int main()
{
    int n;
    cin >> n;
    people p[100];
    for (int i = 0; i < n; i++)
    {
        cin >> p[i].value;
        p[i].number = i + 1;
    }
    queue<people> q;
    //进行入队操作
    for (int i = 0; i < n; i++)
    {
        if (q.empty()) q.push(p[i]);
        else if (q.size() < 5 && q.back().value < p[i].value)  q.push(p[i]);
        else if(q.size()==5 && q.back().value < p[i].value)
        {
            q.pop();
            q.push(p[i]);
        }
    }
    //输出队列
    while (!q.empty())
    {
        cout <<q.front().number << " ";
        q.pop();
    }
    return 0;
}

P.S: 

当考试中需要自己手动实现队列的时候,可以通过数组实现或者链表实现

队列的链式存储: 

struct Node
{
    int item;
    Node* next;
};
struct queue
{
    Node* first;//队头指针
    Node* last;//队尾指针
    int num;
};

相关函数:

bool isEmpty(queue q)
{
    return q.first == NULL;//队列初始化时,头指针和尾指针都为空
}

void enqueue(queue &q, int n)
{
    Node* oldlast = q.last;//先拿到原先的尾指针,后续操作需要用到
    Node* newlast = new Node();
    newlast ->item = n;
    q.last = newlast;
    newlast ->next = NULL;
    if (isEmpty(q)) q.first = q.last;//当队列为空时,元素入队后,头指针和尾指针都指向这个元素
    else
        oldlast ->next = newlast;//正常情况下,需要修改原先的尾指针
    q.num++;
}
int  dequeue(queue& q)
{
    int item = q.first->item;
    q.first = q.first->next;
    if (isEmpty(q)) q.last = NULL;//最后一个元素出队以后,队列变为空,尾指针要手动置空
    q.num--;
    return item;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值