Problem Description
中午買飯的人特多,食堂真是太擁擠了,買個飯費勁,理工大的小孩還是很聰明的,直接奔政通超市,哈哈,確實,政通超市裏面也賣飯,有好幾種菜,做的比食堂好喫多了,價格也不比食堂貴,並且買菜就送豆漿,吸引了不少童鞋。所以有時吧,人還是很多的,排隊是免不了的,悲劇的是超市只有兩個收銀窗口。
問題是這樣的:開始有兩隊人在排隊,現在咱們只研究第一隊,現在我們給每個人一個編號,保證編號各不相同,排在前面的人買完飯就走了,有些人挑完飯就排在後面等待付款,還有一些人比較聰明,看到另一個隊人比較少,直接離開這個隊到另一個隊去了。我要問的是隊的總人數和某個位置上人的編號。
Input
首先輸入一個整數m(m<10000),代表當前有m個人,第二行輸入m個數,代表每個人的編號,第三行輸入一個整數n(n<10000),代表隊列變動和詢問一共n次,以後n行,JOIN X表示編號爲X(保證與以前的編號不同)的人加入;LEAVE Y表示第Y(Y小於當前隊列長度)個位置 上的人離隊 ;ASK Z(Z小於當前隊列長度)表示詢問第Z個位置上的人的編號;FINISH D表示有D個人買完飯離開了;LENGTH表示詢問隊列的長度 。保證所有數據在int 範圍內.
Output
對每個詢問輸出相應的答案,每個答案佔一行。
Sample Input
3
1 2 3
6
JOIN 4
ASK 2
LEAVE 2
LENGTH
FINISH 2
LENGTH
Sample Output
2
3
1
數組解法:
//本方法未用隊首隊尾指針,直接操作的數組
#include <stdio.h>
#include <string.h>
int main()
{
int m, n, process_num, i;//m個人,n次變動或詢問,process_num是變動或詢問時處理的位置,i數組標記用
int a[10000]; //編號
char str[10];
scanf("%d", &m);
for (i = 1; i <= m; i++)
scanf("%d", &a[i]);
scanf("%d", &n);
while (n--)
{
scanf("%s", str);
if (strcmp(str, "JOIN") == 0)
{
i++;
scanf("%d", &a[i]);
m++;
}
else if (strcmp(str, "LEAVE") == 0)
{
scanf("%d", &process_num);
for (i = process_num; i<m; i++)
a[i] = a[i + 1];
m--;
}
else if (strcmp(str, "ASK") == 0)
{
scanf("%d", &process_num);
printf("%d\n", a[process_num]);
}
else if (strcmp(str, "FINISH") == 0)
{
scanf("%d", &process_num);
for (i = 1; i <= (m - process_num); i++)
{
a[i] = a[i + process_num];
}
m = m - process_num;
}
else if (strcmp(str, "LENGTH") == 0)
{
printf("%d\n", m);
}
}
return 0;
}
模擬隊列解法
版本1:
//一般情況下,數組下標0處爲隊首,存數的最大下標處+1爲隊尾
//添加元素,入隊,隊尾指針加一,刪除元素,出隊,隊首指針加一,這樣隊首隊尾重合時就是空隊列
#include <stdio.h>
#include <string.h>
int main()
{
int m, n, process_num;//m個人,n次變動或詢問,process_num是變動或詢問時處理的位置
int a[10000],*front,*rear; //編號
char str[10];
scanf("%d", &m);
front = a;
rear = a;
for (int i = 0; i < m; i++)
{
scanf("%d", &a[i]);
rear = rear+1;
}
scanf("%d", &n);
while (n--)
{
scanf("%s", str);
if (strcmp(str, "JOIN") == 0)
{
scanf("%d", &a[rear-a]); //入隊,隊尾指針加一
rear++;
}
else if (strcmp(str, "LEAVE") == 0)
{
scanf("%d", &process_num);
for (int i = front+process_num-1 -a; i<=rear-2-a; i++)
a[i] = a[i + 1];
rear--;
}
else if (strcmp(str, "ASK") == 0)
{
scanf("%d", &process_num);
printf("%d\n", a[front+process_num-1-a]);
}
else if (strcmp(str, "FINISH") == 0)
{
scanf("%d", &process_num);
for (int i = 1; i<= process_num; i++) //出隊列,隊首指針加一
{
front++;
}
}
else if (strcmp(str, "LENGTH") == 0)
{
printf("%d\n", rear-front);
}
}
return 0;
}
版本2:
//front 和 rear不以指針的形式出現,以int變量來作爲標記量,比上面指針的的好理解
//寫成結構體的形式更標準一些,更像是模擬隊列,使之具備隊列的性質。
#include <stdio.h>
#include <string.h>
struct queue
{
int a[10000];//存數據的隊列數組
int front, rear; //隊首標記,隊尾標記
};
int main()
{
int m, n, process_num;//m個人,n次變動或詢問,process_num是變動或詢問時處理的位置
struct queue my_queue;
char str[10];
scanf("%d", &m);
my_queue.front = 0;
my_queue.rear = 0;
for (int i = 0; i < m; i++)
{
scanf("%d", &my_queue.a[i]);
my_queue.rear = my_queue.rear+1;
}
scanf("%d", &n);
while (n--)
{
scanf("%s", str);
if (strcmp(str, "JOIN") == 0)
{
scanf("%d", &my_queue.a[my_queue.rear]);
my_queue.rear++;
}
else if (strcmp(str, "LEAVE") == 0)
{
scanf("%d", &process_num);
for (int i = my_queue.front+process_num-1 ; i<= my_queue.rear-2; i++)
my_queue.a[i] = my_queue.a[i + 1];
my_queue.rear--;
}
else if (strcmp(str, "ASK") == 0)
{
scanf("%d", &process_num);
printf("%d\n", my_queue.a[my_queue.front+process_num-1]);
}
else if (strcmp(str, "FINISH") == 0)
{
scanf("%d", &process_num);
for (int i = 1; i<= process_num; i++)
{
my_queue.front++;
}
}
else if (strcmp(str, "LENGTH") == 0)
{
printf("%d\n", my_queue.rear- my_queue.front);
}
}
return 0;
}
c++標準庫容器(雙端隊列)解法:
#include "iostream"
#include "deque"
using namespace std;
int main()
{
int m, n, z, a[10000];
char b[10];
deque<int>q;
cin>>m; //m個人
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
for (int i = 0; i <= m - 1; i++)
{
cin>>z; //編號
q.push_back(z);
}
cin>>n; //n次詢問或處理
for (int i = 0; i <= n - 1; i++)
{
cin>>b;
if (!strcmp(b, "JOIN"))
{
cin>>z;
q.push_back(z);
}
else if (!strcmp(b, "ASK"))
{
cin>>z;
for (int j = 0; j <= z - 2; j++)
{
a[j] = q.front();
q.pop_front();
}
cout<<q.front()<<endl;
for (int j = z - 2; j >= 0; j--)
q.push_front(a[j]);
}
else if (!strcmp(b, "LEAVE"))
{
cin>>z;
for (int j = 0; j <= z - 2; j++)
{
a[j] = q.front();
q.pop_front();
}
q.pop_front();
for (int j = z - 2; j >= 0; j--)
q.push_front(a[j]);
}
else if (!strcmp(b, "LENGTH"))
{
cout<<q.size()<<endl;
}
else if (!strcmp(b, "FINISH"))
{
cin>>z;
for (int j = 0; j <= z - 1; j++)
q.pop_front();
}
}
return 0;
}