确定一种排列方式满足题目要求。
首先对于两个大臣分析(联想到排序算法中cmp比较函数,也是按照某种规则比较两个量,这里我们也分析两个),若1和2要交换,需满足max{a0/b1, (a0*a1)/b2} > max{a0/b2, (a0*a2)/b1},同时约去a0, max{1/b1, a1/b2} > max{1/b2, a2/b1},注意到1/b1 <= a2/b1,a1/b2 >= 1/b2。
只需满足a1/b2 > a2/b1, 即a1*b1 > a2*b2。所以我们按照a*b升序排列。
套上高精度乘法, 高精/低精除法模板。
#include <bits/stdc++.h>
using namespace std;
int n;
struct node {
int a, b;
char cnta[10005];//a前缀积(除当前a)
char ca[1005];//a字符
char ans[10005];//获得金币数
//字符均为倒序,用char类型便于直接得到len
int lans;
}mi[1005];//minister
bool cmp(node x, node y) {//按a*b升序排列
return x.a * x.b < y.a * y.b;
}
bool cmp2(node x, node y) {
if (x.lans != y.lans) return x.lans > y.lans;
else {
for (int i = 0; i <= x.lans; i ++)
if (x.ans[i] == y.ans[i]) continue;
else return x.ans[i] > y.ans[i];
}
return 1;
}
void trans(int a, char b[]) {
int p = 0;
while (a) {
b[p ++] = a % 10 + '0';
a /= 10;
}
b[p] = '\0';//结束
}
void mul(char a[], char b[], char c[]) {//高乘
int la = strlen(a), lb = strlen(b);
int x[10005] = {0}, y[10005] = {0}, z[10005] = {0};
for (int i = 0; i < la; i ++) x[i + 1] = a[i] - '0';
for (int i = 0; i < lb; i ++) y[i + 1] = b[i] - '0';
for (int i = 1; i <= la; i ++)
for (int j = 1; j <= lb; j ++)
z[i + j - 1] += x[i] * y[j];
int len = la + lb;
for (int i = 1; i <= len; i ++) {
z[i + 1] += z[i] / 10;
z[i] %= 10;
}
while (!z[len]) len --;
for (int i = 1; i <= len; i ++)
c[i - 1] = z[i] + '0';
}
void div(char a[], int b, char c[]) {//高精/低精
//不需要逆序储存
int re = 0;//记录余数
int x[10005] = {0}, z[10005] = {0};
int la = strlen(a);
for (int i = 0; i < la; i ++) x[la - i] = a[i] - '0';
for (int i = 1; i <= la; i ++) {//模拟竖式除法
z[i] = (re * 10 + x[i]) / b;
re = (re * 10 + x[i]) % b;
}
int p = 1;
while (z[p] == 0 && p < la) p ++;
int p1 = 0;
for (int i = p; i <= la; i ++)
c[p1 ++] = z[i] + '0';
c[p1] = '\0';
}
int main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n; cin >> mi[0].a >> mi[0].b;
for (int i = 1; i <= n; i ++) cin >> mi[i].a >> mi[i].b;
sort(mi + 1, mi + n + 1, cmp);
trans(mi[0].a, mi[0].ca);
mi[0].cnta[0] = '1', mi[0].cnta[1] = '\0';
for (int i = 1; i <= n; i ++) {
trans(mi[i].a, mi[i].ca);
mul(mi[i - 1].cnta, mi[i - 1].ca, mi[i].cnta);//得到前缀积
}
for (int i = 1; i <= n; i ++) {
div(mi[i].cnta, mi[i].b, mi[i].ans);
mi[i].lans = strlen(mi[i].ans);
}
int ans = 1;
for (int i = 2; i <= n; i ++)
if (!cmp2(mi[ans], mi[i])) ans = i;
for (int i = 0; i < mi[ans].lans; i ++)
cout << mi[ans].ans[i];
return 0;
}