恰逢 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,之间用一个空格隔开,分别表示每个大臣左手和右手上的整数。
一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得的金币数。
3
1 1
2 3
7 4
4 6
2
【输入输出样例说明】
按 1 1 1、 2 2 2、 3 3 3 这样排列队伍,获得奖赏最多的大臣所获得金币数为 2 2 2;
按 1 1 1、 3 3 3、 2 2 2 这样排列队伍,获得奖赏最多的大臣所获得金币数为 2 2 2;
按 2 2 2、 1 1 1、 3 3 3 这样排列队伍,获得奖赏最多的大臣所获得金币数为 2 2 2;
按 2 2 2、 3 3 3、 1 1 1这样排列队伍,获得奖赏最多的大臣所获得金币数为 9 9 9;
按 3 3 3、 1 1 1、 2 2 2这样排列队伍,获得奖赏最多的大臣所获得金币数为 2 2 2;
按 3 3 3、 2 2 2、 1 1 1 这样排列队伍,获得奖赏最多的大臣所获得金币数为 9 9 9。
因此,奖赏最多的大臣最少获得 2 2 2 个金币,答案输出 2 2 2。
【数据范围】
对于 20 % 20\% 20% 的数据,有 1 ≤ n ≤ 10 , 0 < a , b < 8 1≤ n≤ 10,0 < a,b < 8 1≤n≤10,0<a,b<8;
对于 40 % 40\% 40% 的数据,有 1 ≤ n ≤ 20 , 0 < a , b < 8 1≤ n≤20,0 < a,b < 8 1≤n≤20,0<a,b<8;
对于 60 % 60\% 60% 的数据,有 1 ≤ n ≤ 100 1≤ n≤100 1≤n≤100;
对于 60 % 60\% 60% 的数据,保证答案不超过 1 0 9 10^9 109;
对于 100 % 100\% 100% 的数据,有 1 ≤ n ≤ 1 , 000 , 0 < a , b < 10000 1 ≤ n ≤1,000,0 < a,b < 10000 1≤n≤1,000,0<a,b<10000。
NOIP 2012 提高组 第一天 第二题
(什么证完了?还不懂?戳我)
#include <bits/stdc++.h>
using namespace std;
const int Maxn = 1000 + 5;
int n, A, B;
struct project {
int a, b;
} hands[Maxn];
int sum[Maxn], tmp[Maxn], p[Maxn], len2, len1, m, P;
inline bool cmp(project A, project B) {
if (A.a * A.b == B.a * B.b) {
return A.b < B.b;
}
return A.a * A.b < B.a * B.b;
}
inline bool Max() {
int i, j;
i = j = 1;
while (p[i] == 0 && i <= len2) {
i++;
}
while (tmp[j] == 0 && j <= len1) {
j++;
}
if (len2 - i + 1 > len1 - j + 1) {
return 0;
}
if (len2 - i + 1 < len1 - j + 1) {
return 1;
}
while (i <= len2 && j <= len1) {
if (p[i] < tmp[j]) {
return 1;
}
if (p[i] > tmp[j]) {
return 0;
}
i++;
j++;
}
return 0;
}
inline void mul(int d) {
for (int i = 1; i <= m; i++) {
sum[i] *= hands[d].a;
}
for (int i = 1; i <= m; i++) {
sum[i + 1] += sum[i] / 10000;
sum[i] %= 10000;
}
if (sum[m + 1] != 0) {
m++;
}
}
inline void div(int d) {
memset(tmp, 0, sizeof(tmp));
len1 = 1;
while (m > 0 && sum[m] == 0) {
m--;
}
P = 0;
bool flag = 0;
for (int i = m; i >= 1; i--) {
P = P * 10000 + sum[i];
tmp[++len1] = P / hands[d].b;
if (tmp[len1] == 0 && !flag) {
len1--;
} else {
flag = 1;
}
P %= hands[d].b;
}
}
inline void work() {
cin >> n >> A >> B;
for (int i = 1; i <= n; i++) {
cin >> hands[i].a >> hands[i].b;
}
sort(hands + 1, hands + n + 1, cmp);
m = 1;
sum[1] = A;
for (int i = 1; i <= n; i++) {
div(i);
if (Max()) {
len2 = len1;
memcpy(p, tmp, sizeof(tmp));
}
mul(i);
}
int i = 0;
while (i <= len2 && p[i] == 0) {
i++;
}
cout << p[i];
i++;
for (; i <= len2; i++) {
if (0 <= p[i] && p[i] <= 9) {
cout << "000" << p[i];
} else if (10 <= p[i] && p[i] <= 99) {
cout << "00" << p[i];
} else if (100 <= p[i] && p[i] <= 999) {
cout << "0" << p[i];
} else {
cout << p[i];
}
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
work();
return 0;
}
想要提升实力?看这里。