資訊
- 路徑:Tournament \ 1-16 \ 1 - Inv 2001 R1 \ Prerequisites
- 分數:1000
題目
程式介面
1 2 3 4 5
| Class Name: Prerequisites Mathod Name: orderClasses Parameters: String[] Returns: String[] Method signature: string[] orderClasses(string[] classSchedule)
|
說明
學生在大學修課時,會遇到複雜的先修課問題,也就是某些課會有要求需先修完另外某些課後才能修,所以我們來寫一支幫助排定修課續順的程式。程式會輸入字串陣列,每一筆資料表示課程與此課程的先修課,格式大致如下:
例如
請依據以下規則排出修課的順序:
- 課程的先修課必須全部修過後才能修。
- 同時有多個課程可以修時,先修課號數字小的。
- 承上,如果數字相同時,則先修系所代碼按字母排序先的。
- 當輸入資料錯誤時,回傳空的字串陣列。例如無法修完先修課或是先修課不存在。
系統保證輸入
- 系所代碼:3 或 4 個字母 [A-Z]。
- 課號:100-999。
- 如果沒有先修課會以冒號結尾。
範例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| 輸入:{ "CSE121: CSE110", "CSE110:", "MATH122:", } 輸出:{"CSE110","CSE121","MATH122"}
輸入:{ "ENGL111: ENGL110", "ENGL110: ENGL111" } 輸出:{}
輸入:{ "ENGL111: ENGL110" } 輸出:{}
輸入:{ "CSE258: CSE244 CSE243 INTR100" "CSE221: CSE254 INTR100" "CSE254: CSE111 MATH210 INTR100" "CSE244: CSE243 MATH210 INTR100" "MATH210: INTR100" "CSE101: INTR100" "CSE111: INTR100" "ECE201: CSE111 INTR100" "ECE111: INTR100" "CSE243: CSE254" "INTR100:" } 輸出:{"INTR100","CSE101","CSE111","ECE111","ECE201","MATH210","CSE254","CSE221","CSE243","CSE244","CSE258"}
|
解法
聽起來類似遊戲的技能樹,要學會 B 技能前先要學會 A 技能,很容易就想要去記錄使用者學習的狀態,找出下一個可以學習的,不過實際上真的這樣子想去寫的話就太複雜,畢竟不是要開發甚麼系統。這邊我利用簡單的減法反向思考,使用過濾和排序逐一取出下一個課程,並將課程從清單中刪去。
語法
採用較易理解的寫法,效能並非最好
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| using System; using System.Collections.Generic; using System.Text;
namespace Prerequisites { class Prerequisites { public string[] orderClasses(string[] classSchedule) { try { List<string> result = new List<string>();
Dictionary<string, List<string>> courses = new Dictionary<string, List<string>>(); foreach (string line in classSchedule) { string[] tmp = line.Split(':'); courses[tmp[0]] = new List<string>(tmp[1].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)); }
string course = Next(courses); while (course != null) { result.Add(course); courses.Remove(course); foreach (List<string> prerequisites in courses.Values) prerequisites.Remove(course); course = Next(courses); } if(courses.Count > 0) return new string[0]; return result.ToArray(); } catch { return new string[0]; } }
private string Next(Dictionary<string, List<string>> courses) { List<string> candidates = new List<string>(); foreach (KeyValuePair<string, List<string>> pair in courses) if (pair.Value.Count == 0) candidates.Add(pair.Key);
if (candidates.Count == 0) return null;
candidates.Sort(Compare); return candidates[0]; }
private int Compare(string cousre1, string course2) { int num1 = int.Parse(cousre1.Substring(cousre1.Length - 3)); int num2 = int.Parse(course2.Substring(course2.Length - 3)); if (num1 == num2) { string code1 = cousre1.Remove(cousre1.Length - 3); string code2 = course2.Remove(course2.Length - 3); return code1.CompareTo(code2); } else return num1.CompareTo(num2); } } }
|
延伸閱讀
上一題 TopCoder Inv 2001 R1 - SquareDigits
下一題 TopCoder Inv 2001 Semi A+B - MatchMaker
TopCoder - 線上程式設計競賽