洛谷 P1080 国王游戏
之前做的时候感觉看不明白,现在做感觉好简单= =
思路
假设现在只有三个人:国王\(k\)、\(x\)、\(y\)
那么有两种排列顺序:
第一种
\(k_a\) | \(k_b\) |
---|---|
\(y_a\) | \(y_b\) |
\(x_a\) | \(x_b\) |
\(val_x=\dfrac{k_ay_a}{x_b}\)
\(val_y=\dfrac{k_a}{y_b}\)
第二种
\(k_a\) | \(k_b\) |
---|---|
\(x_a\) | \(x_b\) |
\(y_a\) | \(y_b\) |
\(val_y=\dfrac{k_ax_a}{y_b}\)
\(val_x=\dfrac{k_a}{x_b}\)
假设交换后更优,那么要有 \(max(y_b, x_ax_b)<max(y_a*y_b,x_b)\),这就是结构体的判断条件,因此按照这样的规则排序之后,得到的就是最小的,这样找最小即可
注意要写高精
代码
别问我为什么是八格缩进,问就是高精是复制的然后有两格的不整齐看不下去就都八格了
/*
Name: P1080 国王游戏
Author: Loceaner
Date: 01/09/20 16:16
Description: 贪心、高精
*/
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int A = 1e5 + 11;
const int B = 1e6 + 11;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
inline int read() {
char c = getchar();
int x = 0, f = 1;
for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
return x * f;
}
namespace BigInteger {
struct Big_integer {
int d[10005], len;
void clean() {while(len > 1 and !d[len - 1]) len--;}
Big_integer() {memset(d, 0, sizeof d);len = 1;}
Big_integer(int num) {*this = num;}
Big_integer operator = (const char* num) {
memset(d, 0, sizeof d);
len = strlen(num);
for (int i = 0; i < len; i++) d[i] = num[len - 1 - i] - '0';
clean();
return *this;
}
Big_integer operator = (int num) {
char s[10005];
sprintf(s, "%d", num);
*this = s;
return *this;
}
Big_integer operator * (const Big_integer &b) const {
int i, j;
Big_integer c;
c.len = len + b.len;
for (j = 0; j < b.len; j++)
for (i = 0; i < len; i++)
c.d[i + j] += d[i] * b.d[j];
for (i = 0; i < c.len - 1; i++) c.d[i + 1] += c.d[i] / 10, c.d[i] %= 10;
c.clean();
return c;
}
Big_integer operator / (const int &b) {
int i, j, a = 0;
Big_integer c = *this;
for (i = len - 1; i >= 0; i--) {
a = a * 10 + d[i];
for (j = 0; j < 10; j++) if (a < b * (j + 1)) break;
c.d[i] = j;
a = a - b * j;
}
c.clean();
return c;
}
bool operator < (const Big_integer &b) const {
if (len != b.len) return len < b.len;
for (int i = len - 1; i >= 0; i--)
if (d[i] != b.d[i])
return d[i] < b.d[i];
return false;
}
string str() const {
char s[10005];
for (int i = 0; i < len; i++) s[len - 1 - i] = d[i] + '0';
return s;
}
};
istream& operator >> (istream& in, Big_integer &x) {
string s;
in >> s;
x = s.c_str();
return in;
}
ostream& operator << (ostream& out, const Big_integer &x) {
out << x.str();
return out;
}
}
using namespace BigInteger;
int n;
Big_integer ans, tmp = 1;
struct node { int a, b; } w[A];
bool cmp(node x, node y) {
return max(y.b, x.a * x.b) < max(x.b, y.a * y.b);
}
signed main() {
n = read();
w[0].a = read(), w[0].b = read();
for(int i = 1; i <= n; i++) w[i].a = read(), w[i].b = read();
sort(w + 1, w + 1 + n, cmp);
tmp = tmp * w[0].a;
for (int i = 1; i <= n; i++) ans = max(ans, tmp / w[i].b), tmp = tmp * w[i].a;
cout << ans << '\n';
return 0;
}
转载不必联系作者,但请声明出处