題目連結:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=103&page=show_problem&problem=481
題目類型: 資料結構, 二叉樹
範例輸入:
23 101 102 1033 201 202 203ENQUEUE 101ENQUEUE 201ENQUEUE 102ENQUEUE 202ENQUEUE 103ENQUEUE 203DEQUEUEDEQUEUEDEQUEUEDEQUEUEDEQUEUEDEQUEUESTOP25 259001 259002 259003 259004 2590056 260001 260002 260003 260004 260005 260006ENQUEUE 259001ENQUEUE 260001ENQUEUE 259002ENQUEUE 259003ENQUEUE 259004ENQUEUE 259005DEQUEUEDEQUEUEENQUEUE 260002ENQUEUE 260003DEQUEUEDEQUEUEDEQUEUEDEQUEUESTOP0
範例輸出:
Scenario #1101102103201202203Scenario #2259001259002259003259004259005260001
題目大意:
有個所謂的team排序, 給出t個隊伍,以及這些隊伍的成員。 然後進行排隊。
ENQUEUE x: 把x插入隊列中時。如果隊列沒有該元素的隊員,則插入隊列的最後面。如果隊列中已經有了他的隊員,那麼插入最後一個隊員之後。
DEQUEUE: 把隊頭的元素刪除,並且輸出
STOP: 停止
解題思路:
本文URL地址:http://www.bianceng.cn/Programming/sjjg/201410/45535.htm
如果對鏈表熟悉,要類比這個過程並不難。 STL 中的list挺好用的, 是雙向迴圈鏈表。 end()成員函數返回連結首位的那個迭代其。 題目的一個關鍵過程是進行查詢元素x時屬於哪個隊伍(可以用二分尋找加速, 提高的速度很客觀),還可以開一個超大的數組,用座標映射元素值,數組儲存隊伍號,這樣的話尋找元素的隊伍只需要O(1)的時間,是最快的。 然後更關鍵的一步是,每次插入位置的尋找,如果每次的插入都要進行尋找一次位置,肯定會TLE。可以另外開一個迭代器數組儲存某隊伍在隊列中的最後一個位置的迭代器。
代碼:
#include<iostream> #include<cstdio> #include<cstring> #include<list> #include<string> #include<algorithm> using namespace std; int t, commandNum,posTeam; int team[1005][1005]; char command[10]; list<int>m_list; list<int>::iterator lastIt[1005]; int ele[1000000]; // 用來來映射元素屬於哪個隊伍。下標對應元素值 // 尋找這個數在哪個隊伍。 int SearchTeam(int num){ int i,j; for(i=0; i<t; ++i){ // 二分尋找 if(binary_search(team[i]+1, team[i]+1+team[i][0], num)) return i; } //如果查不到,返回-1. 其實題目給的元素一定時屬於某一隊的,是我想複雜了 return -1; } void Input(){ int i,j; for(i=0; i<t; ++i){ scanf("%d", &team[i][0]); for(j=1; j<=team[i][0]; ++j){ scanf("%d",&team[i][j]); ele[team[i][j]] = i; } lastIt[i] = m_list.end(); // 進行排序,為二分做準備 sort(team[i]+1, team[i]+1+team[i][0]); } } // 入隊 void Enqueue(int num){ posTeam=SearchTeam(num); // 用下面這種的方法獲得隊伍速度更加快 //posTeam = ele[num]; if(lastIt[posTeam] == m_list.end()){ // 在m_list.end()中插入,效果和push_back一樣 lastIt[posTeam] = m_list.insert(lastIt[posTeam], num); } else{ ++lastIt[posTeam]; lastIt[posTeam] = m_list.insert(lastIt[posTeam], num); } } void Dequeue(){ if(m_list.empty()) return; printf("%d\n", m_list.front()); list<int>::iterator it = lastIt[m_list.front()]; // 如果彈出的那個元素是隊列中剩下的隊伍中的最後一個,要相應的修改 for(int i=0; i<t; ++i){ if(lastIt[i]==m_list.begin()){ lastIt[i] = m_list.end(); break; } } m_list.pop_front(); } void Solve(){ if(!m_list.empty()) m_list.clear(); while(~scanf("%s",command)){ if(!strcmp(command, "STOP")) break; if(!strcmp(command,"ENQUEUE")){ scanf("%d",&commandNum); Enqueue(commandNum); } else if(!strcmp(command,"DEQUEUE")){ Dequeue(); } } } int main(){ freopen("input.txt","r",stdin); int cas=1; while(~scanf("%d",&t) && t){ Input(); printf("Scenario #%d\n", cas++); Solve(); printf("\n"); } return 0; }