【题目描述】
恰逢
H
H
H国国庆,国王邀请
n
n
n位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这
n
n
n位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。
国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。
【输入格式】
第一行包含一个整数
n
n
n,表示大臣的人数。
第二行包含两个整数
a
a
a和
b
b
b,之间用一个空格隔开,分别表示国王左手和右手上的整数。
接下来
n
n
n行,每行包含两个整数
a
a
a和
b
b
b,之间用一个空格隔开,分别表示每个大臣左手和右手上的整数。
【输出格式】
一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得的金币数。
【数据范围】
1
≤
n
≤
1
,
000
,
0
<
a
,
b
<
10000
1≤n≤1,000,0<a,b<10000
1≤n≤1,000,0<a,b<10000
【输入样例】
3
1 1
2 3
7 4
4 6
【输出样例】
2
【分析】
按照 a ∗ b a*b a∗b从小到大进行排序即为最优解,乘除法时需要使用高精度计算。
【代码】
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>
using namespace std;
typedef pair<int, int> PII;
const int N = 1010;
vector<int> sum, res;
PII item[N];
int n;
//高精度sum / x
vector<int> eval_div(vector<int> sum, int x)
{
vector<int> res;
int r = 0;
for (int i = sum.size() - 1; i >= 0; i--)
{
r = r * 10 + sum[i];
res.push_back(r / x);
r %= x;
}
reverse(res.begin(), res.end());
while (res.size() > 1 && res.back() == 0) res.pop_back();//去前导0
return res;
}
//高精度sum * x
vector<int> eval_mul(vector<int> sum, int x)
{
vector<int> res;
int t = 0;
for (int i = 0; i < sum.size() || t; i++)
{
if(i < sum.size()) t += sum[i] * x;
res.push_back(t % 10);
t /= 10;
}
while (res.size() > 1 && res.back() == 0) res.pop_back();//去前导0
return res;
}
int main()
{
cin >> n;
string a, b;
cin >> a >> b;
for (int i = a.size() - 1; i >= 0; i--)
sum.push_back(a[i] - '0');
for (int i = 0; i < n; i++)
{
cin >> item[i].first >> item[i].second;
item[i].first *= item[i].second;
}
sort(item, item + n);//按a * b从小到大排序
for (int i = 0; i < n; i++)
{
int right = item[i].second, left = item[i].first / right;
auto tmp = eval_div(sum, right);
if (tmp.size() > res.size()) res = tmp;
if (tmp.size() == res.size())
for (int i = res.size() - 1; i >= 0; i--)
if (tmp[i] > res[i]) res = tmp;
sum = eval_mul(sum, left);
}
for (int i = res.size() - 1; i >= 0; i--) cout << res[i];
return 0;
}