(NOIP2012提高组)洛谷P1080题解:用贪心策略解决国王游戏
一、问题分析
这道题目要求我们安排大臣的排列顺序,使得获得最多金币的大臣获得的金币尽可能少。关键在于找到正确的排序规则,并处理大数相乘和相除的问题。
二、解题思路
三、关键观察点
排序规则:a[i].left * a[i].right < a[j].left * a[j].right
国王始终在最前面
需要处理大数相乘和相除的问题
四、代码实现
#include <iostream> #include <vector> #include <algorithm> using namespace std; // 高精度整数类 struct BigInt { vector<int> digits; BigInt(int num = 0) { while (num) { digits.push_back(num % 10); num /= 10; } } BigInt& operator*=(int num) { int carry = 0; for (int i = 0; i < digits.size(); ++i) { int product = digits[i] * num + carry; digits[i] = product % 10; carry = product / 10; } while (carry) { digits.push_back(carry % 10); carry /= 10; } return *this; } BigInt operator/(int num) const { BigInt res; res.digits.resize(digits.size()); int remainder = 0; for (int i = digits.size() - 1; i >= 0; --i) { int current = remainder * 10 + digits[i]; res.digits[i] = current / num; remainder = current % num; } while (res.digits.size() > 1 && res.digits.back() == 0) { res.digits.pop_back(); } return res; } bool operator<(const BigInt& other) const { if (digits.size() != other.digits.size()) { return digits.size() < other.digits.size(); } for (int i = digits.size() - 1; i >= 0; --i) { if (digits[i] != other.digits[i]) { return digits[i] < other.digits[i]; } } return false; } }; struct Minister { int left, right; bool operator<(const Minister& other) const { return left * right < other.left * other.right; } }; int main() { int n; cin >> n; Minister king; cin >> king.left >> king.right; vector<Minister> ministers(n); for (int i = 0; i < n; ++i) { cin >> ministers[i].left >> ministers[i].right; } // 按左右手乘积排序 sort(ministers.begin(), ministers.end()); BigInt product(king.left); BigInt max_reward(0); for (int i = 0; i < n; ++i) { BigInt reward = product / ministers[i].right; if (max_reward < reward) { max_reward = reward; } product *= ministers[i].left; } // 输出最大奖励 for (int i = max_reward.digits.size() - 1; i >= 0; --i) { cout << max_reward.digits[i]; } cout << endl; return 0; }
五、代码解析
BigInt类:实现高精度整数的存储和基本运算
Minister结构体:存储大臣的左右手数字,并实现排序规则
主程序:读取输入、排序大臣、计算最大金币数
原创内容 转载请注明出处