**
[問題描述]
有乙個學校的老師共用n個教室,按照規定,所有的鑰匙都必須放在公共鑰匙盒裡,老師不能帶鑰匙回家。每次老師上課前,都從公共鑰匙盒裡找到自己上課的教室的鑰匙去開門,上完課後,再將鑰匙放回到鑰匙盒中。
鑰匙盒一共有n個掛鉤,從左到右排成一排,用來掛n個教室的鑰匙。一串鑰匙沒有固定的懸掛位置,但鑰匙上有標識,所以老師們不會弄混鑰匙。
每次取鑰匙的時候,老師們都會找到自己所需要的鑰匙將其取走,而不會移動其他鑰匙。每次還鑰匙的時候,還鑰匙的老師會找到最左邊的空的掛鉤,將鑰匙掛在這個掛鉤上。如果有多位老師還鑰匙,則他們按鑰匙編號從小到大的順序還。如果同一時刻既有老師還鑰匙又有老師取鑰匙,則老師們會先將鑰匙全還回去再取出。
今天開始的時候鑰匙是按編號從小到大的順序放在鑰匙盒裡的。有k位老師要上課,給出每位老師所需要的鑰匙、開始上課的時間和上課的時長,假設下課時間就是還鑰匙時間,請問最終鑰匙盒裡面鑰匙的順序是怎樣的?
[基本要求]
輸入格式
輸入的第一行包含兩個整數n, k。
接下來k行,每行三個整數w, s, c,分別表示一位老師要使用的鑰匙編號、開始上課的時間和上課的時長。可能有多位老師使用同一把鑰匙,但是老師使用鑰匙的時間不會重疊。
保證輸入資料滿足輸入格式,你不用檢查資料合法性。
輸出格式
輸出一行,包含n個整數,相鄰整數間用乙個空格分隔,依次表示每個掛鉤上掛的鑰匙編號。
樣例輸入
5 24 3 3
2 2 7
樣例輸出
1 4 3 2 5
樣例說明
第一位老師從時刻3開始使用4號教室的鑰匙,使用3單位時間,所以在時刻6還鑰匙。第二位老師從時刻2開始使用鑰匙,使用7單位時間,所以在時刻9還鑰匙。
每個關鍵時刻後的鑰匙狀態如下(x表示空):
時刻2後為1x345;
時刻3後為1x3x5;
時刻6後為143x5;
時刻9後為14325。
要求:
(1)要求從文字檔案中輸入;
(2)根據時間程序,將取走鑰匙和歸還鑰匙分別視為事件,放入佇列中,然後通過每個事件的先後發生對鑰匙盒的狀態進行變更;
演算法設計思想
1.利用佇列儲存鑰匙編號,線性表儲存老師的資訊:老師要取的鑰匙編號,還有取鑰匙和還鑰匙的時間。
2.find_time ( linkqueue &q, linklist &l )
函式裡設定迴圈,從最早取鑰匙時間開始迴圈直到最遲歸還鑰匙時間,迴圈的變數為i,將i視為時刻,迴圈傳入gt_keys ( linkqueue &q , linklist &l , int i )中。
gt_keys()函式執行還鑰匙或取鑰匙操作。
其具體演算法思想為:
(1) 開始遍歷儲存老師資訊的線性表
(2) 若有老師的還鑰匙時間為i,且已拿到鑰匙(if_key=1),則執行還鑰匙操作:遍歷佇列,尋找第乙個為0的鑰匙編號值,並為它賦為這個老師要還的鑰匙編號;
(3) 若有老師的取鑰匙時間為i,且未拿到鑰匙(if_key=0),則執行取鑰匙操作:從佇列中尋找這個老師要拿的鑰匙編號,若存在,則將佇列中這個鑰匙的編號置為0,表示被取走,同時線性表中老師的if_key置為1;
#include
#include
#include
#include
using
namespace std;
int key_num=
0, t_num=0;
//儲存鑰匙數量和老師人數
int start=
0, finish=0;
//最初的取鑰匙時刻,最遲的還鑰匙時刻
//佇列儲存鑰匙資訊
typedef
struct qnode
qnode ,
*queueptr;
//儲存老師所用的鑰匙和開始時間及結束時間
typedef
struct lnode
lnode,
*linklist;
typedef
struct
linkqueue;
//輸出事件佇列狀態
void show_list ( linklist l )
p = p-
>next;
i++;}
}//利用圖形顯示鑰匙盒實時狀態
void image_key ( linkqueue
&q )
p = q.front-
>next;
cout<<
"*****************************"
"** "
;while
( p!=q.rear-
>next )
cout<"*****************************"
<}//從檔案裡讀取線性表資訊
void createlist ( linklist
&l )
read_in >> key_num;
read_in >> t_num;
while
(!read_in.
eof())
p->next =
null
; p = l-
>next;
q = p-
>next;
read_in.
close()
;while
( p )
p = p-
>next;
} start = q-
>start;
//最早取鑰匙的時間
p = l-
>next;
q = p-
>next;
while
( p )
p = p-
>next;
} finish = q-
>finish;
//最遲還鑰匙的時間
}//初始化鑰匙資訊,從1開始賦值
void initqueue ( linkqueue
&q,int n )
}//銷毀佇列
void destroy_q ( linkqueue
&q )
//cout<< "銷毀成功" <<
endl;
}//探空佇列
int empty_q ( linkqueue &q
)//返回佇列長度;
int length_q ( linkqueue &q
)return
( length );}
//根據時刻i執行取鑰匙或還鑰匙操作
void gt_keys ( linkqueue &q
, linklist &l ,
int i )
q = q.front-
>next;
p = l-
>next;
while
( p )
q = q-
>next;}}
//取鑰匙:若時刻i是某老師的取鑰匙時刻,且未拿到鑰匙
else
if( p-
>start==i &&
p->if_key==0)
q = q-
>next;}}
p = p-
>next;}}
//開始走時間,觀察每個時刻所發生的變化
void find_time ( linkqueue
&q, linklist &l )
for( i=
1; i<=finish; i++)}
//輸出最後鑰匙盒的狀態
void look_all ( linkqueue
&q )
p = q.front-
>next;
cout
(p);
cout<}int
main()
測試資料1:
5 71 1 14
3 3 12
1 15 12
2 7 20
3 18 12
4 21 19
5 30 9
顯示鑰匙盒的即時狀態,以及事件佇列的狀態:
最終輸出:12354
線性表 棧 佇列
輔助定義 define maxsize 5 define ok 0 define error 1 typedef int selemtype typedef int status 棧 順序 鏈式 相關結構體定義 順序棧 typedef struct sqstack 順序棧共享空間 typedef s...
線性表 棧,佇列
1.3 棧 棧是一種先進後出的資料結構。只能在一端進行插入和刪除操作的特殊線性表。將資料進入棧稱為壓棧,資料出去稱為彈棧。壓棧 public void push t t 彈棧 public t pop 讓首結點指向第乙個結點的下乙個結點 head.next oldfirst.next 元素個數 1 ...
線性表 棧和佇列
線性表是n個元素的有限序列。表示方法有兩種,一種是順序表示,一種是鏈式表示。順序表示即採用一組位址連續的儲存單元依次儲存線性表的資料元素,通常採用陣列來實現 鏈式表示是用一組任意的儲存單元儲存線性表的資料元素,每一結點包含兩個域 資料域和指標域,資料域儲存資料,指標域儲存後繼儲存位址資訊,實現為 i...