<style> .reveal { color: #ebb362; } </style> # 110-2數學校定必修/跑步勝利方程式 第六組 分配題目:第二、六題 --- ## 一、摘要 ---- - 動機 - 問題描述 - 困難 - 解法 - 結果 --- ## 二、動機 ---- - 雖然操場在整修無法使用,但是我們可以用數學架構起想像的比賽,以邏輯推導如何分配各跑者的圈數及次數,以最少的秒數,拿下接力賽的勝利 --- ## 三、問題描述 ---- 繞圈賽要完成n圈,每班派m人參加以接力賽的方式進行。每個人的圈數自訂。每人至少都要跑1圈,如何分配可使總共所花的時間最少? ---- ### 背景條件 ---- 繞圈賽派出相應人數跑完指定圈數,可自由分配每人跑的圈數,且每人最少跑一圈,可分幾次完成 設一人第k次跑第m圈所花的時間為 <span style="font-size: .7em">(1.2)^(k-1)^(1.1)^(m-1)^</span>,求如何分配使時間最少 ---- ### 問題二 ---- 若A跑一圈需要40秒,B跑一圈需要44秒,C跑一圈需要60秒,3人要合力跑完20圈,這3人如何分配每人的跑步的圈數,讓完成20圈時間最少? ---- ### 問題五 ---- 若A跑一圈需要40秒,B跑一圈需要42秒,C跑一圈需要44秒,D跑一圈需要46秒,E跑一圈需要46秒,這5人如何分配每人的跑步的圈數,讓完成20圈時間最少? --- ## 四、困難 ---- - 發現:其中一個例題三人所花時間成等差 - 驗證結果:特例 - 結論:找不出通則 --- ## 五、解法 ---- - 工人智慧:excel大法-輸入方程式,讓電腦跑出數據,再人力一一排名 ![](https://i.imgur.com/SrbZxGu.png) - 程式窮舉:將人力比對使用的邏輯交給電腦來執行 ---- <!-- .slide: style="font-size: .4em;" --> ### 甲選手 | 趟數\\圈數 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |-|-|-|-|-|-|-|-| | 1 | 1 | 1.1 | 1.21 | 1.331 | 1.4641 | 1.61051 | 1.771561 | | 2 | 1.2 | 1.32 | 1.452 | 1.5972 | 1.75692 | 1.932612 | 2.1258732 | | 3 | 1.44 | 1.584 | 1.7424 | 1.91664 | 2.108304 | 2.3191344 | 2.55104784 | | 4 | 1.728 | 1.9008 | 2.09088 | 2.299968 | 2.5299648 | 2.78296128 | 3.061257408 | | 5 | 2.0736 | 2.28096 | 2.509056 | 2.7599616 | 3.03595776 | 3.339553536 | 3.67350889 | ---- <!-- .slide: style="font-size: .4em;" --> ### 乙選手 | 趟數\\圈數 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |-|-|-|-|-|-|-|-| | 1 | 1.1 | 1.21 | 1.331 | 1.4641 | 1.61051 | 1.771561 | 1.9487171 | | 2 | 1.32 | 1.452 | 1.5972 | 1.75692 | 1.932612 | 2.1258732 | 2.33846052 | | 3 | 1.584 | 1.7424 | 1.91664 | 2.108304 | 2.3191344 | 2.55104784 | 2.806152624 | | 4 | 1.9008 | 2.09088 | 2.299968 | 2.5299648 | 2.78296128 | 3.061257408 | 3.367383149 | | 5 | 2.28096 | 2.509056 | 2.7599616 | 3.03595776 | 3.339553536 | 3.67350889 | 4.040859779 | ---- <!-- .slide: style="font-size: .4em;" --> ### 丙選手 | 趟數\\圈數 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |-|-|-|-|-|-|-|-| | 1 | 1.5 | 1.65 | 1.815 | 1.9965 | 2.19615 | 2.415765 | 2.6573415 | | 2 | 1.8 | 1.98 | 2.178 | 2.3958 | 2.63538 | 2.898918 | 3.1888098 | | 3 | 2.16 | 2.376 | 2.6136 | 2.87496 | 3.162456 | 3.4787016 | 3.82657176 | | 4 | 2.592 | 2.8512 | 3.13632 | 3.449952 | 3.7949472 | 4.17444192 | 4.591886112 | | 5 | 3.1104 | 3.42144 | 3.763584 | 4.1399424 | 4.55393664 | 5.009330304 | 5.510263334 | ---- ### 各圈排名 ---- <!-- .slide: style="font-size: .4em;" --> ### 甲選手 | 趟數\\圈數 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |-|-|-|-|-|-|-|-| | 1 | 1 | 2 | 5 | 9 | 14 | 21 | 29 | | 2 | 4 | 7 | 12 | 19 | 28 | 37 | 47 | | 3 | 11 | 17 | 25 | 35 | 46 | 56 | 66 | | 4 | 24 | 33 | 43 | 54 | 65 | 74 | 82 | | 5 | 42 | 52 | 62 | 72 | 81 | 88 | 94 | <!-- ---- --> ### 乙選手 | 趟數\\圈數 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |-|-|-|-|-|-|-|-| | 1 | 2 | 5 | 9 | 14 | 21 | 29 | 39 | | 2 | 7 | 12 | 19 | 27 | 37 | 47 | 58 | | 3 | 17 | 25 | 35 | 45 | 56 | 66 | 76 | | 4 | 33 | 43 | 55 | 64 | 74 | 82 | 90 | | 5 | 52 | 62 | 73 | 80 | 88 | 94 | 99 | <!-- ---- --> ### 丙選手 | 趟數\\圈數 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |-|-|-|-|-|-|-|-| | 1 | 16 | 23 | 32 | 41 | 51 | 61 | 71 | | 2 | 31 | 40 | 50 | 60 | 70 | 79 | 87 | | 3 | 49 | 59 | 69 | 78 | 86 | 93 | 98 | | 4 | 68 | 77 | 85 | 92 | 97 | 101 | 103 | | 5 | 84 | 91 | 96 | 100 | 102 | 104 | 105 | ---- ## 程式邏輯概述 ---- - 輸入甲、乙、丙、目標圈數後,程式會: 1. 將各選手的各圈相關資訊(該圈秒數、選手代號、是第幾趟&圈)打包好後,一個個全部存入一維容器A中 ---- 3. 將容器中的每圈資料依照**該圈秒數**進行遞增排序 4. 窮舉出所有選手的**趟數分配**,共會有$n-人數+1$種可能(例如傳接棒:甲->乙->丙和甲->乙->甲->乙便是其中兩種可能) ---- 6. 依照各個趟數條件,在容器中找尋符合條件的前n個,就可以得出該趟數分配下的最短秒數及甲乙丙分別跑的圈數,打包並存入另一個一維容器B 7. 將B中的$n-人數+1$個內容物,以所花秒數進行遞增排序 8. 印出B中前五項的秒數及甲乙丙的各圈&趟分配 ---- ![](https://i.imgur.com/SejJxLq.png) --- ## 六、結果 ---- - 利用excel可應對多種不同的問題,只要修改數據即可 - 未找到通式 - 可設計程式輸入背景數據,讓程式跑出最短秒數 ---- ### 答案 ---- - 第二題、甲(5, 3, 2)乙(4, 3, 1)丙(1, 1) -> 1098.376秒 - 第五題、甲(4, 2)乙(3, 2)丙(2, 1)丁(2, 1)戊(2) --- ## 七、感想&展望 ---- - 工欲善其事,必先利其器 - 並非所有問題均有通則 --- ## 八、小組分工 ---- 楊軒輊:簡報製作、討論問題、試算表操作 蕭名凱:程式撰寫、簡報格式設定&製作、討論問題、試算表操作 黃俞華、林品辰、鄭力文、林貽建:分享意見、討論問題 --- ## 附錄:程式原始碼 ---- ```c++=1 #include <iostream> #include <cmath> #include <vector> #include <utility> #include <algorithm> #include <iomanip> using namespace std; using vec = vector<pair<double,vector<int>>>; using mypair = pair<double,vector<int>>; vec create_player(int id, int sec, int n){ vec v; for(int i = 0; i < (n/3+1); i++){ for(int j = 0; j < (n/3+1); j++){ mypair cell; cell.first = (sec*pow(1.2, i)*pow(1.1, j)); // cout << cell.first << endl; cell.second = {id, i+1, j+1}; v.push_back(cell); } } return v; } template <class T> bool sort_function(T i, T j){return (i.first < j.first); } template <class T> void print_vector(T a){ for(auto it = a.begin(); it!= a.end(); ++it){ cout << it->first << " (" << it->second[0] << ", " << it->second[1] << ", " << it->second[2] << ")\n"; } } template <class T> void print_anss(T a){ for(auto it = a.begin(); it!= a.begin()+5; ++it){ cout<< it->first << "s => {"; for(auto it2 = it->second.begin(); it2!= it->second.end(); ++it2){ cout << "("; for(int i = 0; i < (*it2).size(); i++){ cout<< (*it2)[i]; if (i == ((*it2).size()-1))break; cout << ", "; } if(it2 == (it->second.end()-1)){ cout << ")"; break; }; cout << "), "; } cout << "}\n"; } } template <class T> vec merge_and_sort(T p1, T p2, T p3){ vec all; all.insert(all.end(), p1.begin(), p1.end()); all.insert(all.end(), p2.begin(), p2.end()); all.insert(all.end(), p3.begin(), p3.end()); sort(all.begin(), all.end(), sort_function<pair<double, vector<int>>>); // print_vector<vec>(all); //測試用 return all; } vector<pair<double,vector<vector<int>>>> brute_force(int goal, vec sorted_data){ int p1t, p2t, p3t; p1t = p2t = p3t = 1; vector<pair<double,vector<vector<int>>>> v; int _cycle = 1; while(p1t+p2t+p3t <= goal){ int count = p1t+p2t+p3t; double total = 0; pair<double,vector<vector<int>>> p; p.second.push_back(vector<int>(p1t, 1)); p.second.push_back(vector<int>(p2t, 1)); p.second.push_back(vector<int>(p3t, 1)); for(auto it = sorted_data.begin(); it != sorted_data.end(); ++it){ if(it->second[0] == 1 && (it->second)[1] <= p1t && it->second[2] == 1){ total += it->first; } else if(it->second[0] == 2 && (it->second)[1] <= p2t && it->second[2] == 1){ total += it->first; } else if(it->second[0] == 3 && (it->second)[1] <= p3t && it->second[2] == 1){ total += it->first; } } if(count == goal){ p.first = total; v.push_back(p); break; } for(auto it = sorted_data.begin(); it != sorted_data.end(); ++it){ if(it->second[2] == 1)continue; if(it->second[0] == 1 && (it->second)[1] <= p1t){ count++; total += it->first; p.second[0][it->second[1]-1]++; } else if(it->second[0] == 2 && (it->second)[1] <= p2t){ count++; total += it->first; p.second[1][it->second[1]-1]++; } else if(it->second[0] == 3 && (it->second)[1] <= p3t){ count++; total += it->first; p.second[2][it->second[1]-1]++; } if(count == goal){ p.first = total; v.push_back(p); break; } if(_cycle == 1){ p1t++; _cycle++; } else if(_cycle == 2){ p2t++; _cycle++; } else if (_cycle == 3){ p3t++; _cycle = 1; } } sort(v.begin(), v.end(), sort_function<pair<double,vector<vector<int>>>>); return v; } int main(){ cout << fixed; // cout << "(請依序輸入:p1初始一圈所花時間 p2的 p3的 要跑的總圈數)\n"; cout << "input format: p1 p2 p3 n\n"; int p1, p2, p3, n; while(cin){ cin >> p1 >> p2 >> p3 >> n; vec p1vec = create_player(1, p1, n); vec p2vec = create_player(2, p2, n); vec p3vec = create_player(3, p3, n); vec all = merge_and_sort<vec>(p1vec, p2vec, p3vec); vector<pair<double,vector<vector<int>>>> anss = brute_force(n, all); print_anss<vector<pair<double,vector<vector<int>>>>>(anss); //測試用 // cout << (*a)[n]->first << " " << (*a)[n]->second[0] << (*a)[n]->second[1]; // cout << all[n].first << " (" << all[n].second[0] << ", " << a[n].second[1] // << ", " << all[n].second[2] << ")\n"; } return 0; }
{"metaMigratedAt":"2023-06-16T16:21:20.357Z","metaMigratedFrom":"YAML","title":"110-2數學校定必修:繞圈賽","breaks":true,"slideOptions":"{\"spotlight\":null,\"transition\":\"convex\"}","contributors":"[{\"id\":\"beac2943-c493-437f-91d2-fab50ce0d252\",\"add\":11169,\"del\":533},{\"id\":\"36baa91a-6493-4ce8-9897-5a1c2df94155\",\"add\":49,\"del\":1906},{\"id\":\"2718addf-3548-4248-974b-37b4ec708050\",\"add\":695,\"del\":322}]","description":"第六組 分配題目:第二、六題"}
    544 views