题目描述
恰逢 HH国国庆,国王邀请nn 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 nn 位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。
国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。
输入格式
第一行包含一个整数nn,表示大臣的人数。
第二行包含两个整数 aa和 bb,之间用一个空格隔开,分别表示国王左手和右手上的整数。
接下来 nn行,每行包含两个整数aa 和 bb,之间用一个空格隔开,分别表示每个大臣左手和右手上的整数。
输出格式
一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得的金币数。
输入输出样例
输入
3 1 1 2 3 7 4 4 6
输出
2
贪心证明:设国王为king,大臣为p1, p2。
可列 king l0 r0 king l0 r0
p1 l1 r1 p2 l2 r2
p2 l2 r2 p1 l1 r1
则 k1 = l0 / r1, k2 = l0 * l1 / r2, k3 = l0 / r2, k4 = l0 * l2 / r1。
ans1 = max(k1, k2), ans2 = max(k3, k4);
显然 k2 > k3, k4 > k1, 所以若 ans1 > ans2, 则 k2 > k4, 即 l1 * r1 > i2 * r2 ;
所以sort时按 a * b 为优先级即可。
(高精度运算为板子, 不多解释)
#include <iostream> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <stack> #include <stdio.h> #include <cmath> #include <string.h> #include <vector> #define ll long long using namespace std; int n, lens = 1, lenm = 1, lena = 1; int sum[10010] = {0, 1}, maxn[10010] = {0, 1}, ans[10010]; struct of{ ll l, r; bool operator < (const of x) const { return l * r < x.l * x.r; //按左右手金币乘积为优先级排序 } }coin[1001]; void times(ll x) //高精度乘法 { int t = 0; for(int i = 1; i <= lens; i++) sum[i] *= x; for(int i = 1; i <= lens; i++) { t += sum[i]; sum[i] = t % 10; t /= 10; } while(t != 0) { lens++; sum[lens] = t % 10; t /= 10; } } void div(ll x) //高精度除法 { memset(ans, 0, sizeof(ans)); lena = lens; int t = 0; for(int i = lens; i >= 1; i--) { t *= 10; t += sum[i]; if(t >= x) { ans[i] = t /x; t %= x; } } while(ans[lena] == 0) { if(lena == 1) break; lena--; } } void max() //高精度比较 { if(lena > lenm) { for(int i = 1; i <= lena; i++) maxn[i] = ans[i]; lenm = lena; } else if(lena == lenm) { for(int i =lena; i >= 1; i--) if(maxn[i] < ans[i]) { for(int j = 1; j <= lena; j++) maxn[j] = ans[j]; lenm = lena; break; } } } int main() { ios::sync_with_stdio(false); cin >> n; cin >> coin[0].l >> coin[0].r; for(int i = 1; i <= n; i++) cin >> coin[i].l >> coin[i].r; sort(coin + 1, coin + n + 1); for(int i = 1; i <=n; i++) { times(coin[i - 1].l); div(coin[i].r); max(); } for(int i = lenm; i >= 1; i--) cout << maxn[i]; return 0; }