開啟章節選單
10273 Eat or Not to Eat?
題目連結
題目敘述
一位年輕的農夫有 N 頭奶牛,但牠們產的牛奶量實在非常非常少
John 無法僅靠這些少量的牛奶維生
所以他打算吃掉其中「表現最差」的幾頭牛以度過饑餓
每天 John 會選出當天產奶量最少的那頭牛並將其吃掉
如果當天有多頭牛並列為最低產奶量
John 會因為猶豫不決而不會吃任何牛(耶!太好了!)。
第 i 頭牛的產奶週期為 Ti
也就是說,若牠在某天產了 L 單位的牛奶
那麼在 Ti 天後,若牠尚未被吃掉
將會再度產 L 單位的牛奶。
雖然 John 並不聰明
但他懷疑所有牛最終是否都會被吃光,因此請你幫助他
別忘了,他會提供一些美味的牛肉作為回報!
輸入說明
輸入的第一行包含一個整數 T,表示測試案例的數量(1 ≤ T ≤ 50)。
每個測試案例先有一行整數 N(1 ≤ N ≤ 1000),代表奶牛的數量。
接下來有 N 行,對應第 i 頭牛:
- 首先是一個整數 Ti(1 ≤ Ti ≤ 10),表示該頭牛的產奶週期;
- 接著有 Ti 個整數 Mj(0 ≤ Mj ≤ 250),分別表示該頭牛在週期內第 j 天所能產的牛奶量。
輸出說明
對於每個測試案例,輸出一行,包含兩個整數 C、D:
- C:最終不會被吃掉的奶牛數量;
- D:當最後一頭被吃掉的牛被吃掉時,已經過的天數。
若沒有任何奶牛被吃掉,則第二個數字請輸出 0。
程式碼
#include <bits/stdc++.h> using namespace std; #define INF LONG_LONG_MAX/1000 #define int long long signed main() { int t; cin >> t; while (t--) { int n, m, tmp; cin >> n; // 讀取牛隻總數 N vector<vector<int>> v(n); // 使用二維陣列 v 存放每頭牛的週期性生產量 for (int i = 0; i < n; i++) { cin >> m; // 讀取第 i 頭牛的生產週期長度 Ti while (m--) { cin >> tmp; // 讀取週期中某一天的產量 v[i].push_back(tmp); // 將該天產量加入第 i 頭牛的資料陣列 } } // lastday:最後一次宰殺動作發生的天數(0-base) // cnt:已宰殺牛隻總數 int lastday = -1, cnt = 0; vector<int> kill(n); // kill[i] = 1 表示第 i 頭牛已被宰殺,否則為 0 for (int day = 0; day - lastday <= 2520; day++) { // 模擬每日作業,終止條件:自上次宰殺日起連續 2520 天(Ti 跟 Mj 的最小公倍數)內未再發生宰殺 int mn = INF; // 當日檢測到的最小產量 int cowID = -1; // 對應最小產量的牛隻索引 for (int i = 0; i < n; i++) { // 遍歷所有尚未被宰殺的牛隻,尋找當日唯一最少產量 if (kill[i]) continue; // 牛被殺掉就跳過 int milk = v[i][day%v[i].size()]; // 以 day % 週期長度 取當日產量 if (milk < mn) { // 發現更小產量時,更新最小值及對應牛隻索引 mn = milk; cowID = i; } else if (milk == mn) cowID = -1; // 若有多頭牛隻產量相同且為最小,標註為無法確定唯一最少 } if (~cowID) { // 若存在唯一最少產量的牛隻,則進行宰殺動作 kill[cowID] = 1; // 標記該牛隻已被宰殺 lastday = day; // 更新最後一次宰殺的天數索引 cnt++; // 累計宰殺數量 } } cout << n-cnt << ' ' << lastday+1 << '\n'; // 最後輸出 } }