您的位置:首页 > 数据库

MemSQL Start[c]UP 2.0 - Round 2 - Online Round A,B,C

2014-08-11 13:16 393 查看


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
, B
;
long long a
, b
;

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
, b
, 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
;
vector<int> g
;

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: