在清华举办美食节的某一天的早上10点钟,有N个人试图去生煎包处排队,10点前发生了M个事件,事件大概分为以下4种
有人从队尾进入队伍
有人插队
有人等不及了从队伍中离开
要求10点钟时整个队伍的情况
输入格式:
输入第一行有两个用空格隔开的数N,M
接下来有M行,按时间先后顺序每行表述一个事件
I x:表示编号为x的人从队尾进入队伍
C x y:表示编号为x的人插队,排在y前一位
L x:表示编号为x的人从队伍中离开(这个人有可能还会回来)
我们保证同一时刻队伍里不会出现两个编号相同的人,也不会让没有进入队伍的人离开队伍且数据合法。
输出格式:
输出1行,表示队首到队尾所有人的编号,用空格隔开;如果队伍没有人输出“Bai Ren Zhan”(不含引号)
输入样例:
4 4
I 1
I 2
C 3 2
C 4 1
输出样例:
4 1 3 2
用数组能做,想试试链表但是说段错误,但示例能过。
using namespace std;
struct q{
int number;
struct q* next;
};
void rudui(int n,struct q** tail){//末尾入队操作
struct q* temp=new q{n,NULL};
(tail)->next=temp;
tail=temp;
}
void chadui(int x,int y, struct q head){//插队
struct q temp=head->next;
struct q* befor=temp;
while(temp->number!=y){
befor=temp;
temp=temp->next;
}
struct q* cha=new q{x,NULL};
if(temp == head){
cha->next = head->next;
head->next = cha;
} else {
befor->next=cha;
cha->next=temp;
}
}
void chudui(int x,struct q* head){//出队
struct q* temp=head->next;
struct q* befor=temp;
while(temp->number!=x){
befor=temp;
temp=temp->next;
}
if(head->nexttemp){
head->next=temp->next;
}else{
befor->next=temp->next;
}
}
int main(){
int n,m;
struct q* head;
struct q* tail;
struct q* body;
head=tail=body=new q{0,NULL};
cin>>n>>m;
int i;
for(i=0;i<m;i++){
char c;
int x;
cin>>c>>x;
if(c'I'){
rudui(x,&tail);
}else if(c'C'){
int y;
cin>>y;
chadui(x,y,head);
}else if(c'L'){
chudui(x,head);
}
}
body=head->next;
while(body!=NULL){//输出
cout<<body->number<<' ';
body=body->next;
}
return 0;
}
在C++中,我们可以使用链表(Linked List)来模拟这个排队过程。下面是一个可能的实现方案:
#include <iostream>
#include <unordered_map>
using namespace std;
struct Node {
int id;
Node* next;
Node(int id) : id(id), next(nullptr) {}
};
class Queue {
private:
Node* head;
Node* tail;
unordered_map<int, Node*> idToNode;
public:
Queue() : head(nullptr), tail(nullptr) {}
void enqueue(int id) {
Node* newNode = new Node(id);
if (!head) {
head = newNode;
tail = newNode;
} else {
tail->next = newNode;
tail = newNode;
}
idToNode[id] = newNode;
}
void dequeue(int id) {
if (!head) return;
Node* prev = nullptr;
Node* curr = head;
while (curr && curr->id != id) {
prev = curr;
curr = curr->next;
}
if (!curr) return; // Person not found in the queue
if (prev) {
prev->next = curr->next;
} else {
head = curr->next;
}
if (curr == tail) {
tail = prev;
}
idToNode.erase(id);
delete curr;
}
void insertBefore(int id, int beforeId) {
if (!head) return;
Node* beforeNode = idToNode[beforeId];
if (!beforeNode) return; // Person to insert before not found
Node* newNode = new Node(id);
if (head == beforeNode) {
newNode->next = head;
head = newNode;
} else {
Node* prev = head;
while (prev->next && prev->next != beforeNode) {
prev = prev->next;
}
if (prev->next == beforeNode) {
newNode->next = beforeNode;
prev->next = newNode;
}
}
idToNode[id] = newNode;
}
void printQueue() {
if (!head) {
cout << "Bai Ren Zhan" << endl;
return;
}
Node* curr = head;
while (curr) {
cout << curr->id << " ";
curr = curr->next;
}
cout << endl;
}
};
int main() {
int N, M;
cin >> N >> M;
Queue q;
char type;
int id, beforeId;
for (int i = 0; i < M; ++i) {
cin >> type;
if (type == 'I') {
cin >> id;
q.enqueue(id);
} else if (type == 'C') {
cin >> id >> beforeId;
q.insertBefore(id, beforeId);
} else if (type == 'L') {
cin >> id;
q.dequeue(id);
}
}
q.printQueue();
return 0;
}
在这个实现中,我们定义了一个Node
结构体来表示队列中的每个节点,每个节点包含一个人的编号和指向下一个节点的指针。Queue
类管理这些节点,并提供enqueue
(入队)、dequeue
(出队)和insertBefore
(插队)方法。我们还使用了一个unordered_map
来快速查找节点,以便根据人的编号进行插队和离队操作。
主函数main
中,我们读取输入,根据事件类型调用相应的方法,并在最后打印出队列的情况。如果队列为空,则输出"Bai Ren Zhan"。