MemSQL Start[c]UP 2.0 - Round 2 - Online Round
不得不说这场真心不好打啊...
A:黄金分割进制数,满足一个性质,对于第i位xi=xi?1+xi?2,这样一来就可以把所有位推到前两位去比较大小,不过单单这样直接搞果断爆longlong无限WA8,最后发现在推的过程中,有一位上面差值大于1,就可以直接判断了
B:不得不吐槽一下毛子的英语,Today‘s ying yu is very hao,题目看了非常非常久,不能更逗。其实看懂的就挺简单了,只要贪心分别考虑A放入B和B放入A的情况,然后判断是用复制好还是移动好即可
C:三分,设f(x)为其他人选票都小于x,自己选票大于等于x需要的开销,这样一开很容易证明f(x)是一个下凹的单峰函数,就可以用三分法求解了
代码:
A:
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const double eps = 1e-10; const int N = 100005; char A[N], B[N]; long long a[N], b[N]; int main() { scanf("%s%s", A, B); int an = strlen(A); int bn = strlen(B); for (int i = 0; i < an; i++) a[i] = A[an - i - 1] - '0'; for (int i = 0; i < bn ; i++) b[i] = B[bn - i - 1] - '0'; int n = max(an, bn); for (int i = n - 1; i >= 2; i--) { if (a[i] >= b[i] ){ a[i] -= b[i]; b[i] = 0; } else if (a[i] <= b[i]) { b[i] -= a[i]; a[i] = 0; } if (a[i] >= 2) { printf(">\n"); return 0; } if (b[i] >= 2) { printf("<\n"); return 0; } a[i - 1] += a[i]; a[i - 2] += a[i]; b[i - 1] += b[i]; b[i - 2] += b[i]; } long long aa = a[0], bb = a[1]; long long cc = b[0], dd = b[1]; long long x = 2 * (aa - cc) - (dd - bb); long long y = (dd - bb); if (x < 0 && y > 0) { printf("<\n"); } else if (x > 0 && y < 0) { printf(">\n"); } else if (x >= 0 && y >= 0) { x = x * x; y = y * y * 5; if (x == y) printf("=\n"); else if (x < y) printf("<\n"); else printf(">\n"); } else { x = x * x; y = y * y * 5; if (x == y) printf("=\n"); else if (x < y) printf(">\n"); else printf("<\n"); } return 0; }
B:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef unsigned long long ll; const int N = 100005; ll a[N], b[N], suma, sumb, n, m; int main() { scanf("%llu%llu", &n, &m); for (int i = 0; i < n; i++) { scanf("%llu", &a[i]); suma += a[i]; } for (int i = 0; i < m; i++) { scanf("%llu", &b[i]); sumb += b[i]; } sort(a, a + n); sort(b, b + m); ll ans = 10000000000000000000ULL; ll sum = 0; for (ll i = 0; i < n - 1; i++) { if (sumb <= a[i]) { sum += (n - i) * sumb; ans = min(ans, sum); break; } sum += a[i]; } ans = min(ans, sum + sumb); sum = 0; for (ll i = 0; i < m - 1; i++) { if (suma <= b[i]) { sum += (m - i) * suma; ans = min(ans, sum); } sum += b[i]; } ans = min(ans, sum + suma); printf("%llu\n", ans); return 0; }
C:
#include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int INF = 0x3f3f3f3f; const int N = 100005; int n, save[N]; vector<int> g[N]; int cal(int x) { int ans = 0, have = g[0].size(), sn = 0; for (int i = 1; i <= 100000; i++) { int j = 0; if (x <= g[i].size()) { for (; j < g[i].size() - x + 1; j++) { ans += g[i][j]; have++; } } for (; j < g[i].size(); j++) save[sn++] = g[i][j]; } sort(save, save + sn); for (int i = 0; i < x - have; i++) ans += save[i]; return ans; } int main() { scanf("%d", &n); int a, b; for (int i = 0; i < n; i++) { scanf("%d%d", &a, &b); g[a].push_back(b); } for (int i = 1; i <= 100000; i++) sort(g[i].begin(), g[i].end()); int l = 1, r = n; while (l < r - 2) { int midl = (l * 2 + r) / 3; int midr = (l + r * 2) / 3; if (cal(midl) > cal(midr)) l = midl; else r = midr; } int ans = INF; for (int i = l; i <= r; i++) ans = min(ans, cal(i)); printf("%d\n", ans); return 0; }
MemSQL Start[c]UP 2.0 - Round 2 - Online Round A,B,C,布布扣,bubuko.com