Contest Info


[Practice Link](https://codeforc.es/gym/102007)

Solved A B C D E F G H I J K
8/11 O O O - - O O - O O O
  • O 在比赛中通过
  • Ø 赛后通过
  • ! 尝试了但是失败了
  • - 没有尝试

Solutions


A A Prize No One Can Win

签到。

view code
#include <bits/stdc++.h>
using namespace std; const int N = 1e5 + 10;
int n, a[N], x; int main() {
while (scanf("%d%d", &n, &x) != EOF) {
for (int i = 1; i <= n; ++i) scanf("%d", a + i);
sort(a + 1, a + 1 + n);
int res = 1;
for (int i = 2; i <= n; ++i) {
if (a[i] + a[i - 1] <= x) {
++res;
} else break;
}
printf("%d\n", res);
}
return 0;
}

B Birthday Boy

题意:

给出\(n\)个生日,现在要找个日期,使得在它前面离它最近的生日和它相距的天数最大,如果有多个,输出和\(10-27\)相距天数最大的。

思路:

题意读清楚就可以了,枚举每一天。

view code
#include <bits/stdc++.h>
using namespace std; using pII = pair <int, int>;
#define fi first
#define se second
int n; pII a[110]; char s[110];
int mon[] = {
0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
bool operator < (pII a, pII b) {
if (a.fi < b.fi || (a.fi == b.fi && a.se <= b.se)) {
return true;
}
return false;
}
int dis(pII a, pII b) {
if (a < b) {
if (a.fi == b.fi) return b.se - a.se;
int res = mon[a.fi] - a.se;
for (int i = a.fi + 1; i < b.fi; ++i) res += mon[i];
res += b.se;
return res;
} else {
int res = mon[a.fi] - a.se;
for (int i = a.fi + 1; i <= 12; ++i) res += mon[i];
for (int i = 1; i < b.fi; ++i) res += mon[i];
res += b.se;
return res;
}
} int main() {
while (scanf("%d", &n) != EOF) {
for (int i = 1; i <= n; ++i) scanf("%s %02d-%02d", s, &a[i].fi, &a[i].se);
sort(a + 1, a + 1 + n, [&](pII x, pII y) {
if (x.fi != y.fi) return x.fi < y.fi;
return x.se < y.se;
});
pII res = pII(-1, -1); int Max = -1;
a[0] = a[n];
int pos = 0;
for (int i = 1; i <= 12; ++i) {
for (int j = 1; j <= mon[i]; ++j) {
pII t = pII(i, j);
while (pos < n && a[pos + 1] < t) ++pos;
if (dis(a[pos], t) > Max) {
Max = dis(a[pos], t);
res = t;
} else if (dis(a[pos], t) == Max) {
if (dis(pII(10, 28), t) < dis(pII(10, 28), res)) {
res = t;
}
}
}
}
printf("%02d-%02d\n", res.fi, res.se);
}
return 0;
}

C Cardboard Container

题意:

给出一个立方体的体积\(V\),算表面积

思路:

枚举长宽高,长宽高是\(V\)的因子,枚举量不大。

view code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
void getfac(vector <int> &vec, int n) {
vec.clear();
for (int i = 1; 1ll * i * i <= n; ++i) {
if (n % i == 0) {
vec.push_back(i);
if (i * i != n)
vec.push_back(n / i);
}
}
} int main() {
int n;
while (scanf("%d", &n) != EOF) {
vector <int> vec_a;
getfac(vec_a, n);
ll res = 1e18;
for (auto a : vec_a) {
vector <int> vec_b;
getfac(vec_b, n / a);
for (auto &b : vec_b) {
int c = n / a / b;
res = min(res, 2ll * (a * b + a * c + b * c));
}
}
printf("%lld\n", res);
}
return 0;
}

D Driver Disagreement

题意:

给出\(n\)个点的图,每个点都有两条边,并且每个点有一个标记\(1\)或者\(0\)

现在两个人在同一点,但是他们不知道自己在哪一点,一个人觉得他们在\(A\),另一个人觉得他们在\(B\)。

然后他们所在的位置是\(A\)或者\(B\)

现在需要设计一种路线,使得沿着路线走,如果从\(A\)出发走到一个点和从\(B\)出发走到一个点那个点的标记不一样,那么它们就知道谁对谁错了。

现在问最少的路线长度。

这个路线是每次选择往左走还是往右走,因为每个点有两条边

E Entirely Unsorted Sequences

题意:

有\(n\)个数,定义一个数是有序的当且仅当它左边的数都小于等于它,它右边的数都大于等于它。

现在问有多少种这些数的排列,使得所有数都不是有序的。

F Financial Planning

题意:

给出一些理财产品,对于每个理财产品,刚开始需要投入\(c_i\)的钱,之后每一天都会获得\(p_i\)的钱。

过了\(x\)天,一款理财产品带来的收益是\(xp_i - c_i\)。

现在问,如果选择理财产品,使得\(x\)天后的收益大于等于\(M\)

要满足\(x\)最小

思路:

二分\(x\),那么每款理财产品的收益固定,贪心的取。

view code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int n, m, p[N], c[N];
bool check(ll x) {
ll res = 0;
for (int i = 1; i <= n; ++i) {
ll t = 1ll * p[i] * x - c[i];
res += max(0ll, t);
if (res >= m) return true;
}
return res >= m;
} int main() {
while (scanf("%d%d", &n, &m) != EOF) {
for (int i = 1; i <= n; ++i) scanf("%d%d", p + i, c + i);
ll l = 0, r = 2e9, res = 2e9;
while (r - l >= 0) {
ll mid = (l + r) >> 1;
if (check(mid)) {
r = mid - 1;
res = mid;
} else {
l = mid + 1;
}
}
printf("%lld\n", res);
}
return 0;
}

G Game Night

题意:

有一个长度为\(n\)的字符串环,里面只有'A', 'B', 'C'三种字符。

问最少要移动多少个字符,使得同类字符所在的位置的连续的。

思路:

枚举最终形态,那么如果一个位置最终形态对应的位置不是本身,那么这个字符要动。

维护三个前缀和\(O(1)\)算贡献。

view code
#include <bits/stdc++.h>
using namespace std; const int N = 1e5 + 10;
int n, A[N], B[N], C[N]; char s[N];
int get(char c, int l, int r) {
if (l > r) return 0;
if (c == 'A') return (A[r] - A[l - 1]);
else if (c == 'B') return (B[r] - B[l - 1]);
return (C[r] - C[l - 1]);
}
int gao(string t) {
int num[3];
for (int i = 0; i < 3; ++i)
num[i] = get(t[i], 1, n);
int res = 0;
for (int i = 0; i <= num[0]; ++i) {
res = max(res, get(t[0], 1, i) + get(t[1], i + 1, i + num[1]) + get(t[2], i + num[1] + 1, i + num[1] + num[2]) + get(t[0], i + num[1] + num[2] + 1, n));
}
return n - res;
} int main() {
while (scanf("%d%s", &n, s + 1) != EOF) {
memset(A, 0, sizeof A);
memset(B, 0, sizeof B);
memset(C, 0, sizeof C);
for (int i = 1; i <= n; ++i) {
A[i] = A[i - 1] + (s[i] == 'A');
B[i] = B[i - 1] + (s[i] == 'B');
C[i] = C[i - 1] + (s[i] == 'C');
}
int res = 1e9;
string t = "ABC";
do {
res = min(res, gao(t));
} while (next_permutation(t.begin(), t.end()));
printf("%d\n", res);
}
return 0;
}

H Harry the Hamster

题意:

有一张\(n\)个点\(m\)条边的有向图,每条边有边权,一个人在\(S\)点,它的左脑不想睡觉,它的右脑想睡觉。

两个脑袋轮流操作,每次操作在当前点选择一条出边往下走。

保证除了\(T\)点之外每个点都有出边,并且\(T\)没有出边。

问两个脑袋都最优操作,最终能否到\(T\),能的话就输出到\(T\)的时间,不能的话就输出'infinity'

I In Case of an Invasion, Please. . .

题意:

给出一张\(n\)个点\(m\)条边的无向图,每个点有\(p_i\)个人,有\(s(1 \leq s \leq 10)\)个保护区。

每个保护区有一个容量\(c_i\),保证\(\sum c_i \geq \sum p_i\).

现在所有人都要到保护区,令所有人到保护区的最大时间最小。

思路:

二分答案,那么对于每个点,我们可以知道在这个答案下,这个点上的人可以到达哪些保护区。

那么用一个\(s\)的二进制状态表示它的可达状态,发现最多只有\(2^s\)种状态。

将同种状态的点都缩起来,网络流判断是否流量等于\(\sum p_i\)即可。

view code
#include <bits/stdc++.h>

using namespace std;

using ll = long long;

const int N = 2e5 + 10;
const ll INFLL = 0x3f3f3f3f3f3f3f3f; struct Dicnic {
static const int M = 2e6 + 10;
static const int N = 1e4 + 10; struct Edge {
int to, nxt;
ll flow; Edge() {} Edge(int to, int nxt, ll flow): to(to), nxt(nxt), flow(flow) {}
}edge[M]; int S, T;
int head[N], tot;
int dep[N]; void Init() {
memset(head, -1, sizeof head);
tot = 0;
} void set(int _S, int _T) {
S = _S;
T = _T;
} void addedge(int u, int v, ll w, ll rw = 0) {
edge[tot] = Edge(v, head[u], w); head[u] = tot++;
edge[tot] = Edge(u, head[v], rw); head[v] = tot++;
} bool BFS() {
memset(dep, -1, sizeof dep);
queue<int>q;
q.push(S);
dep[S] = 1;
while (!q.empty()) {
int u = q.front();
q.pop();
for (int i = head[u]; ~i; i = edge[i].nxt) {
if (edge[i].flow && dep[edge[i].to] == -1) {
dep[edge[i].to] = dep[u] + 1;
q.push(edge[i].to);
}
}
}
return dep[T] >= 0;
} ll DFS(int u, ll f) {
if (u == T || f == 0) {
return f;
}
ll w, used = 0;
for (int i = head[u]; ~i; i = edge[i].nxt) {
if (edge[i].flow && dep[edge[i].to] == dep[u] + 1) {
w = DFS(edge[i].to, min(f - used, edge[i].flow));
edge[i].flow -= w;
edge[i ^ 1].flow += w;
used += w;
if (used == f) return f;
}
}
if (!used) dep[u] = -1;
return used;
} ll solve() {
ll res = 0;
while (BFS()) {
res += DFS(S, INFLL);
}
return res;
}
}dicnic; struct Edge {
int to, nxt;
ll w; Edge() {} Edge(int to, int nxt, ll w): to(to), nxt(nxt), w(w){}
}edge[N << 2]; int n, m, s;
int a[N], c[N], p[N];
int head[N], used[N], tot;
ll dis[11][N]; void Init() {
memset(head, -1, sizeof head);
tot = 0;
} void addedge(int u, int v, int w) {
edge[tot] = Edge(v, head[u], w); head[u] = tot++;
edge[tot] = Edge(u, head[v], w); head[v] = tot++;
} struct qnode {
int u;
ll w; qnode() {} qnode(int u, ll w): u(u), w(w) {} bool operator < (const qnode &other) const {
return w > other.w;
}
}; void Dij(int id, int S) {
for (int i = 1; i <= n; ++i) {
dis[id][i] = INFLL;
used[i] = false;
}
dis[id][S] = 0;
priority_queue<qnode> pq;
pq.push(qnode(S, 0));
while (!pq.empty()) {
int u = pq.top().u;
pq.pop();
if (used[u]) continue;
used[u] = true;
for (int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].to, w = edge[i].w;
if (!used[v] && dis[id][v] > dis[id][u] + w) {
dis[id][v] = dis[id][u] + w;
pq.push(qnode(v, dis[id][v]));
}
}
}
} ll sum;
ll mark[1 << 11]; bool check(ll x) {
memset(mark, 0, sizeof mark);
for (int i = 1; i <= n; ++i) {
int S = 0;
for (int j = 1; j <= s; ++j) {
if (dis[j][i] <= x) {
S |= 1 << (j - 1);
}
}
mark[S] += p[i];
}
dicnic.Init();
int S = (1 << s) + s + 10, T = S + 1, tmp = 1 << s;
dicnic.set(S, T);
for (int i = 0; i < tmp; ++i) {
dicnic.addedge(S, i, mark[i]);
for (int j = 0; j < s; ++j) {
if (i & (1 << j)) {
dicnic.addedge(i, j + tmp, mark[i]);
}
}
}
for (int i = (1 << s), j = 1; j <= s; ++j, ++i) {
dicnic.addedge(i, T, c[j]);
}
ll res = dicnic.solve();
return res == sum;
} int main() {
while (scanf("%d %d %d", &n, &m, &s) != EOF) {
Init();
sum = 0;
for (int i = 1; i <= n; ++i) {
scanf("%d", p + i);
sum += p[i];
}
for (int i = 1, u, v, w; i <= m; ++i) {
scanf("%d %d %d", &u, &v, &w);
addedge(u, v, w);
}
for (int i = 1; i <= s; ++i) {
scanf("%d %d", a + i, c + i);
}
for (int i = 1; i <= s; ++i) {
Dij(i, a[i]);
}
ll l = 0, r = INFLL, res = INFLL;
while (r - l >= 0) {
ll mid = (l + r) >> 1;
if (check(mid)) {
r = mid - 1;
res = mid;
} else {
l = mid + 1;
}
}
printf("%lld\n", res);
}
return 0;
}

J Janitor Troubles

题意:

给出四条边,问这四条边构成的四边形的最大面积

思路:

四边形是内接圆四边形时最大。

view code
#include <bits/stdc++.h>

using namespace std;

using db = double;

const db eps = 1e-8;

int sgn(db x) {
if (fabs(x) < eps) return 0;
else return x > 0 ? 1 : -1;
} inline db F(db a, db b, db c) {
db p = (a + b + c) / 2.0;
db res = sqrt(p * (p - a) * (p - b) * (p - c));
return res;
} inline db f(db a, db b, db c, db d) {
db res = 0.0;
db l = max(fabs(a - b), fabs(c - d));
db r = min(fabs(a + b), fabs(c + d));
for (db e = l; e < r; e += 0.0005) {
if (a + b - e <= 0) continue;
if (a + e - b <= 0) continue;
if (b + e - a <= 0) continue; if (c + d - e <= 0) continue;
if (c + e - d <= 0) continue;
if (d + e - a <= 0) continue; res = max(res, F(a, b, e) + F(c, d, e));
}
return res;
} int a, b, c, d; int main() {
while (scanf("%d %d %d %d", &a, &b, &c, &d) != EOF) {
if (a == b && b == c && c == d) {
db res = a * b;
printf("%.10f\n", res);
continue;
}
db res = f(a, b, c, d);
res = max(res, f(a, c, b, d));
res = max(res, f(a, d, b, c));
printf("%.15f\n", res);
}
return 0;
}

K Kingpin Escape

题意:

给出一棵树,有一个特殊点,现在可以额外加一些边,使得不管删去原树中的哪条边,每个点仍然可以到达特殊点

view code
#include <bits/stdc++.h>

using namespace std;

int n, m;
vector<vector<int> >G;
vector<int> vec; void gao(int u, int fa) {
if (G[u].size() == 1) {
vec.push_back(u);
return ;
}
for (auto &v : G[u]) if (v != fa){
gao(v, u);
}
} int main() {
while (scanf("%d %d", &n, &m) != EOF) {
G.clear();
G.resize(n);
vec.clear();
for (int i = 1, u, v; i < n; ++i) {
scanf("%d %d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
if (n == 2) {
puts("1");
puts("0 1");
continue;
}
int rt = 0;
for (int i = 0; i < n; ++i) {
if (G[i].size() > 1) {
rt = i;
break;
}
}
gao(rt, rt);
int sze = vec.size();
int cnt = (sze + 1) / 2;
printf("%d\n", cnt);
for (int i = 0; i + cnt < sze; ++i) {
printf("%d %d\n", vec[i], vec[i + cnt]);
}
if (sze & 1) {
if (vec[cnt - 1] != m) {
printf("%d %d\n", vec[cnt - 1], m);
} else {
printf("%d %d\n", vec[cnt - 1], vec[cnt - 2]);
}
}
}
return 0;
}

2018 Benelux Algorithm Programming Contest (BAPC 18)的更多相关文章

  1. 2018 Benelux Algorithm Programming Contest (BAPC 18)I In Case of an Invasion, Please. . .

    题意:一副无向有权图,每个点有一些人,某些点是避难所(有容量),所有人要去避难所,问最小时间所有人都到达避难所, 题解:dij+二分+最大流check,注意到避难所最多10个,先挨个dij求到避难所的 ...

  2. Gym -102007 :Benelux Algorithm Programming Contest (BAPC 18) (寒假自训第5场)

    A .A Prize No One Can Win 题意:给定N,S,你要从N个数中选最多是数,使得任意两个之和不大于S. 思路:排序,然后贪心的选即可. #include<bits/stdc+ ...

  3. 2014 Benelux Algorithm Programming Contest (BAPC 14)E

    题目链接:https://vjudge.net/contest/187496#problem/E E Excellent Engineers You are working for an agency ...

  4. 2017 Benelux Algorithm Programming Contest (BAPC 17) Solution

    A - Amsterdam Distance 题意:极坐标系,给出两个点,求最短距离 思路:只有两种方式,取min  第一种,先走到0点,再走到终点 第二种,走到同一半径,再走过去 #include ...

  5. 2015 Benelux Algorithm Programming Contest (BAPC 15)E - Excellent Engineers

    这题想了很久没思路,不知道怎么不sort维护二维的最小值 emmmm原来是线段树/树状数组,一维sort,二维当成下标,维护三维的最小值 #include<bits/stdc++.h> # ...

  6. 2018 German Collegiate Programming Contest (GCPC 18)

    2018 German Collegiate Programming Contest (GCPC 18) Attack on Alpha-Zet 建树,求lca 代码: #include <al ...

  7. (寒假GYM开黑)2018 German Collegiate Programming Contest (GCPC 18)

    layout: post title: 2018 German Collegiate Programming Contest (GCPC 18) author: "luowentaoaa&q ...

  8. Benelux Algorithm Programming Contest 2014 Final(第二场)

    B:Button Bashing You recently acquired a new microwave, and noticed that it provides a large number ...

  9. 2020.3.14--训练联盟周赛 Preliminaries for Benelux Algorithm Programming Contest 2019

    1.A题 题意:给定第一行的值表示m列的最大值,第m行的值表示n行的最大值,问是否会行列冲突 思路:挺简单的,不过我在一开始理解题意上用了些时间,按我的理解是输入两组数组,找出每组最大数,若相等则输出 ...

随机推荐

  1. 【Qt】Qt5.12连接MySQl5.7(亲自测试成功)

    目录 00. 目录 01. Qt5.12连接MySQL5.7测试代码 02. Qt5.12连接MySQL5.7问题描述 03. 解决办法 04. 结果测试 05. 打赏 00. 目录 01. Qt5. ...

  2. Linux下 sftp服务配置

    查看openssh的版本,使用ssh -V 命令来查看openssh的版本,版本必须大于4.8p1,低于的这个版本需要升级. 参考博客:https://yq.aliyun.com/articles/6 ...

  3. mouseenter 与 mouseover 区别于选择

    mouseover事件, 箭头在子元素移动会触发冒泡事件,  子元素的鼠标箭头可触父元素方法, 相反,mouseenter事件功能与mouseover类似, 但鼠标进入某个元素不会冒泡触发父元素方法. ...

  4. KaiWu 的体验

    KaiWu 的体验 来源 https://www.zhihu.com/question/28950444 >>>>>>>>>>>> ...

  5. JS 客户端(浏览器)存储数据之 localStorage、sessionStorage和indexDB

    基本概念 1.localStorage和sessionStorage是HTML5 Web存储的提供的两种存储方式,在IE7以上以及大多数浏览器都是支持的 2.localStorage和sessionS ...

  6. 使用swap扩展内存

    当系统在内存不够用的时,新建一个swap文件,这个文件可以把内存中暂时不用的传输到对应的swap文件上,相当于扩展了内存的大小,具体使用方法如下: swap文件可以自己选择放在哪里,自己新建一个对应的 ...

  7. weblogic jdbc 相关概念介绍

    weblogic jdbc 是什么? 如何配置? 常见问题? 如何监控?

  8. S5PV210 时钟

    CLOCK DOMAINS 时钟域 S5PV210 consists of three clock domains, namely, main system (MSYS), display syste ...

  9. webstorm编写react native,代码修改后,重新编译运行没有变化的问题

    w我是拷贝一份react native代码到另一台电脑,发现修改代码运行之后不显示修改后的效果,即仍然与原来的效果一样,暂时不知道什么原因, 后来我运行了npm install 就可以了,不知道是不是 ...

  10. ORA-28547: connection to server failed, probable Oracle Net admin error

    现象 C:\Users\Administrator>sqlplus scott/tiger@192.168.1.11:1521/orcl SQL*Plus: Release 11.2.0.4.0 ...