結果
問題 |
No.1281 Cigarette Distribution
|
ユーザー |
![]() |
提出日時 | 2025-05-14 13:06:42 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 7,871 bytes |
コンパイル時間 | 1,019 ms |
コンパイル使用メモリ | 97,752 KB |
実行使用メモリ | 16,064 KB |
最終ジャッジ日時 | 2025-05-14 13:08:08 |
合計ジャッジ時間 | 5,044 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 12 TLE * 1 -- * 10 |
ソースコード
#include <iostream> #include <vector> #include <numeric> #include <map> #include <set> #include <vector> #include <algorithm> // Function to calculate the product of counts modulo MOD // Takes the vector of counts and the number of boxes X as input long long calculate_goodness(const std::vector<long long>& counts, int X) { long long product = 1; long long MOD = 1e9 + 7; // The modulus value bool has_zero = false; // Flag to check if any box count is zero // Iterate through all X boxes for (int i = 0; i < X; ++i) { if (counts[i] == 0) { // If any box has 0 cigarettes, the product ("goodness") is 0 has_zero = true; break; // No need to check further boxes } // Multiply the current product by the count of cigarettes in the box, modulo MOD product = (product * counts[i]) % MOD; } if (has_zero) { return 0; // Return 0 if any box was empty } return product; // Return the final product modulo MOD } int main() { // Use faster I/O operations std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); int N; // Number of steps (operations) int M_limit; // Maximum number of boxes X to calculate for std::cin >> N >> M_limit; // Read N and M long long MOD = 1e9 + 7; // Modulo value defined in the problem // Iterate through each required number of boxes X from 1 to M_limit for (int X = 1; X <= M_limit; ++X) { // Initialize the state for X boxes std::vector<long long> counts(X, 0); // Stores counts for each box, index 0 to X-1. Initially all 0. // Data structure to efficiently find boxes with minimum counts. // Maps count value to a set of box indices having that count. // Using std::map ensures counts are ordered, so map.begin() gives the minimum count. // Using std::set for indices ensures indices are ordered, useful for tie-breaking (smallest index). std::map<long long, std::set<int>> counts_map; // Set to keep track of indices of boxes that are currently empty (count = 0). std::set<int> empty_boxes; // Initially, all X boxes are empty. Fill the set. for (int i = 0; i < X; ++i) { empty_boxes.insert(i); } // Simulate the N steps of adding and removing cigarettes for (int step = 0; step < N; ++step) { // A-kun's move: Add 2 cigarettes based on strategy int target_idx = -1; // The index of the box A-kun chooses to add cigarettes to // A-kun's strategy: Prioritize filling empty boxes. if (!empty_boxes.empty()) { // If there are empty boxes, A picks one (smallest index due to set iteration properties). target_idx = *empty_boxes.begin(); // Get the smallest index of an empty box. empty_boxes.erase(empty_boxes.begin()); // Remove this box index from the empty set. // This box now receives 2 cigarettes (goes from 0 to 2). counts[target_idx] = 2; counts_map[2].insert(target_idx); // Add this box to the map under count 2. } else { // If there are no empty boxes, A picks a box with the minimum count. // Defensive check: If counts_map is empty, it implies there are no non-empty boxes. // This state should not be reachable under normal operation if X > 0. if (counts_map.empty()) { continue; // Skip step if state is invalid. } // Get the minimum count present among non-empty boxes. long long min_count = counts_map.begin()->first; // Get the smallest index among boxes with this minimum count. target_idx = *counts_map[min_count].begin(); // Remove the chosen box from the set associated with its current count (min_count). counts_map[min_count].erase(counts_map[min_count].begin()); // If this set becomes empty, remove the count entry from the map to keep it clean. if (counts_map[min_count].empty()) { counts_map.erase(min_count); } // Update the box's count (increases by 2). counts[target_idx] = min_count + 2; // Add the box index to the set associated with its new count (min_count + 2). counts_map[min_count + 2].insert(target_idx); } // B-kun's move: Remove 1 cigarette based on strategy int remove_idx = -1; // The index of the box B-kun chooses to remove a cigarette from // Check if there are any boxes with exactly 1 cigarette. Use find for efficiency. auto it_map = counts_map.find(1); if (it_map != counts_map.end() && !it_map->second.empty()) { // B-kun's priority: If boxes with count 1 exist, target one of them to minimize goodness (to 0). remove_idx = *it_map->second.begin(); // Get the smallest index box with count 1. // Remove this box from the count 1 set in the map. it_map->second.erase(it_map->second.begin()); // If the set for count 1 becomes empty, remove the count 1 entry from the map. if (it_map->second.empty()) { counts_map.erase(it_map); } // The count of this box becomes 0. counts[remove_idx] = 0; empty_boxes.insert(remove_idx); // Add this box index back to the set of empty boxes. } else { // If no boxes have count 1, B targets a box with the minimum positive count (which must be >= 2). if (counts_map.empty()) { // If counts_map is empty, it means all boxes are empty. B cannot move. continue; } // Find the minimum count among non-empty boxes. Since the count 1 case is handled, this count must be >= 2. long long min_pos_count = counts_map.begin()->first; // Defensive check: the minimum count must be positive. if (min_pos_count <= 0) { continue; // Skip B's move if state seems invalid. } // Get the smallest index box with this minimum count. remove_idx = *counts_map.begin()->second.begin(); // Remove this box from the set associated with its current count (min_pos_count). counts_map.begin()->second.erase(counts_map.begin()->second.begin()); // If this set becomes empty, remove the count entry from the map. if (counts_map.begin()->second.empty()) { counts_map.erase(counts_map.begin()); } // Update the box's count (decreases by 1). counts[remove_idx] = min_pos_count - 1; // Add the box index to the set associated with its new count. // Since min_pos_count >= 2, the new count `min_pos_count - 1` is >= 1. // The box remains non-empty. counts_map[counts[remove_idx]].insert(remove_idx); } } // After N steps, calculate the final "goodness" using the helper function. long long final_goodness = calculate_goodness(counts, X); // Output the result for the current value of X. std::cout << final_goodness << "\n"; } return 0; // Indicate successful execution. }