排隊買飯(數組解法 和 模擬隊列 和 雙端隊列 )

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;
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章