Contest Info

Practice Link

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

Solutions

Problem A. Accurate Movement

签到题。

代码:

view code
#include <bits/stdc++.h>
using namespace std;
int ceil(int x, int y) {
return (x + y - 1) / y;
} int main() {
int a, b, n;
while (scanf("%d%d%d", &a, &b, &n) != EOF) {
int res = ceil(n - b, b - a) + ceil(n - a, b - a);
printf("%d\n", res);
}
return 0;
}

Problem B. Bad Treap

题意:

令Treap的一对二维点权为\((f, sin(x))\),现在要给出\(n\)个\(x\),使得这个Treap的深度最大

思路:

考虑很小的时候,\(x = sin(x)\),那么它两维都是单调的,深度最大

代码:

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

using namespace std;

int main() {
int n;
scanf("%d", &n);
for (long long i = 1; i <= n; ++i)
printf("%lld\n", i * 710 - 710 * 25000);
return 0;
}

Problem E. Equidistant

题意:

给出一棵树,再给定\(m\)个点,现在要找一个点,使得这个点到\(m\)个点的距离相等

思路:

以\(m\)个点作为起点跑多源最短路,但是同时要记录到点\(x\)的最短路径条数,当最短路径条数为\(m\)的时候,那么这个点就是合法的

代码:

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

using namespace std;

const int N = 2e5 + 10;

int n, m;
int dep[N], sze[N], a[N], vis[N];
vector<vector<int> >G; void gao() {
queue<int> q;
for (int i = 1; i <= m; ++i) q.push(a[i]);
while (!q.empty()) {
int u = q.front();
q.pop();
for (auto &v : G[u]) {
if (dep[v] == 0 || dep[v] == dep[u] + 1) {
dep[v] = dep[u] + 1;
sze[v] += sze[u];
if (sze[v] == m) {
printf("YES\n%d\n", v);
return ;
}
if (!vis[v]) {
q.push(v);
vis[v] = 1;
}
}
}
}
puts("NO");
} int main() {
while (scanf("%d %d", &n, &m) != EOF) {
G.clear();
G.resize(n + 1);
memset(dep, 0, sizeof dep);
memset(sze, 0, sizeof sze);
memset(vis, 0, sizeof vis);
for (int i = 1, u, v; i < n; ++i) {
scanf("%d %d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
for (int i = 1; i <= m; ++i) {
scanf("%d", a + i);
dep[a[i]] = 1;
sze[a[i]] = 1;
vis[a[i]] = 1;
}
if (n == 1) {
puts("YES\n1");
} else {
gao();
}
}
return 0;
}

Problem H. High Load Database

题意:

给出\(n\)个数\(a_i(\sum a_i \leq 10^6)\),\(q\)次询问给出一个\(t_i\),问将这\(n\)个数分成若干个连续段,使得每段之和不超过\(t_i\)的最小段数

思路:

考虑单次询问显然可以贪心合并,但是我们可以维护一个前缀和,每次二分跳下一个位置,所以处理一个询问的时间是\(O(\text{段数}logn)\)。

并且考虑\(\sum a_i \leq 10^6\),所以所有可行询问的总段数不会很多,直接暴力即可。

代码:

view code
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int n, q, Max, a[N], sum[N], ans[N], vis[N]; int getans(int limit) {
if (vis[limit]) return ans[limit];
vis[limit] = 1;
if (Max > limit) {
return ans[limit] = -1;
}
if (limit <= 1000) {
int res = 1, pre = 0;
for (int i = 1; i <= n; ++i) {
if (a[i] + pre <= limit) {
pre += a[i];
} else {
pre = a[i];
++res;
}
}
return ans[limit] = res;
} else {
int res = 0, pos = 0;
while (pos < n) {
++res;
int nx = upper_bound(sum + 1, sum + 1 + n, limit + sum[pos]) - sum - 1;
pos = nx;
}
return ans[limit] = res;
}
} int main() {
while (scanf("%d", &n) != EOF) {
memset(vis, 0, sizeof vis);
sum[0] = 0;
for (int i = 1; i <= n; ++i) {
scanf("%d", a + i);
Max = max(Max, a[i]);
sum[i] = sum[i - 1] + a[i];
}
scanf("%d", &q);
while (q--) {
int need; scanf("%d", &need);
int res = getans(need);
if (res == -1) puts("Impossible");
else printf("%d\n", res);
}
}
return 0;
}

Problem I. Ideal Pyramid

代码:

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

using namespace std;

const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f; struct node {
int x, y, z; node() {} node(int x, int y, int z): x(x), y(y), z(z) {}
}a[N]; int n;
int x, y; bool ok(int h) {
int l = -INF, r = INF, u = INF, d = -INF;
for (int i = 1; i <= n; ++i) {
if (h < a[i].z) return false;
int x = h - a[i].z;
l = max(l, a[i].x - x);
r = min(r, a[i].x + x);
u = min(u, a[i].y + x);
d = max(d, a[i].y - x);
}
if (l > r || d > u) return false;
x = l, y = d;
return true;
} int main() {
while (scanf("%d", &n) != EOF) {
for (int i = 1; i <= n; ++i) {
scanf("%d %d %d", &a[i].x, &a[i].y, &a[i].z);
}
int l = 0, r = INF, res = INF;
x = INF, y = INF;
while (r - l >= 0) {
int mid = (l + r) >> 1;
if (ok(mid)) {
r = mid -1;
res = mid;
} else {
l = mid + 1;
}
}
ok(res);
printf("%d %d %d\n", x, y, res);
}
return 0;
}

Problem J. Just the Last Digit

题意:

有一个\(n\)个点的有向图,\(i\) 到 \(j\)有边,那么必然有\(i < j\)。

现在给出\(a_{i, j} = i \rightarrow j\)的路径条数模\(10\)的结果,要你还原这个图。

思路:

正着推,考虑新加入一个点\(k\)的时候,我们枚举一个点\(i(i < k)\),如果\(i\)到\(k\)通过点\(j(i < j < k)\)中转的路径之和模\(10\)不等于\(a_{i, j}\),那么\(i \rightarrow k\)这条边是存在的,否则不存在

代码:

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

using namespace std;

typedef long long ll;

const int N = 510;

int n;
char a[N][N];
int res[N][N]; int main() {
while (scanf("%d", &n) != EOF) {
memset(res, 0, sizeof res);
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
scanf(" %c", &a[i][j]);
}
}
for (int i = 1; i <= n; ++i) {
for (int j = i + 1; j <= n; ++j) {
int sum = 0;
for (int k = i + 1; k < j; ++k) {
if (res[i][k]) sum += a[k][j] - '0';
}
if ((sum + 1) % 10 == a[i][j] - '0') res[i][j] = 1;
}
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
printf("%d", res[i][j]);
}
puts("");
}
}
return 0;
}

Problem K. King’s Children

题意:

给出一个\(n \cdot m\)的矩形,上面的'.'表示空地,字母表示国王的儿子,'A'表示大儿子。

现在要给每个儿子划分城市,每个城市必须是一个矩形,每块空地只能属于一个城市,一个城市里面只能包含一个儿子。

但是大儿子划分得到的空地数量要尽可能的多,但不一定是最多。

思路:

对'A'找一个极大子矩形,挖空后将剩下的分完。

考虑两种分法:

  • 先竖向扩展,然后横向扩展
  • 先横向扩展,然后竖向扩展

这两种分法不可能同时不成立,不太知道为啥(猜的)。。

代码:

view code
#include <bits/stdc++.h>
using namespace std;
#define dbg(x...) do { cout << "\033[32;1m" << #x << " -> "; err(x); } while(0)
void err() { cout << "\033[39;0m" << endl; }
template <class T, class... Ts> void err(const T&arg, const Ts&... args) { cout << arg << " "; err(args...); }
const int N = 1e3 + 10;
const int INF = 0x3f3f3f3f;
int n, m, ax, ay;
char str[N][N], stra[N][N], strb[N][N];
int up[N][N], down[N][N];
int X[N], Y[N]; void gaoA(char str[][N], int l, int r) {
int MinU = INF, MinD = INF;
for (int i = l; i <= r; ++i) {
MinU = min(MinU, up[ax][i]);
MinD = min(MinD, down[ax][i]);
}
for (int i = l; i <= r; ++i) {
for (int j = 1; j <= MinU; ++j) {
str[ax - j + 1][i] = 'a';
}
for (int j = 1; j <= MinD; ++j) {
str[ax + j - 1][i] = 'a';
}
}
str[ax][ay] = 'A';
} void gaoU(char str[][N]) {
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (str[i][j] > 'A' && str[i][j] <= 'Z') {
up[i][j] = i;
for (int o = 1; ; ++o) {
if (i - o < 1) break;
if (str[i - o][j] != '.') break;
up[i][j] = i - o;
str[i - o][j] = str[i][j] - 'A' + 'a';
}
}
}
}
} void gaoD(char str[][N]) {
for (int i = 1; i <= n; ++i) {
for (int j = m; j >= 1; --j) {
if (str[i][j] > 'A' && str[i][j] <= 'Z') {
down[i][j] = i;
for (int o = 1; ; ++o) {
if (i + o > n) break;
if (str[i + o][j] != '.') break;
down[i][j] = i + o;
str[i + o][j] = str[i][j] - 'A' + 'a';
}
}
}
}
} void gaoL(char str[][N]) {
for (int j = 1; j <= m; ++j) {
for (int i = 1; i <= n; ++i) {
if (str[i][j] > 'A' && str[i][j] <= 'Z') {
for (int o = j - 1; o >= 1; --o) {
int F = 1;
for (int k = up[i][j]; k <= down[i][j]; ++k) {
if (str[k][o] != '.') {
F = 0;
break;
}
}
if (!F) break;
for (int k = up[i][j]; k <= down[i][j]; ++k) {
str[k][o] = str[i][j] - 'A' + 'a';
}
}
}
}
}
} void gaoR(char str[][N]) {
for (int j = m; j >= 1; --j) {
for (int i = 1; i <= n; ++i) {
if (str[i][j] > 'A' && str[i][j] <= 'Z') {
for (int o = j + 1; o <= m; ++o) {
int F = 1;
for (int k = up[i][j]; k <= down[i][j]; ++k) {
if (str[k][o] != '.') {
F = 0;
break;
}
}
if (!F) break;
for (int k = up[i][j]; k <= down[i][j]; ++k) {
str[k][o] = str[i][j] - 'A' + 'a';
}
}
}
}
}
} void gaoU1(char str[][N]) {
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (str[i][j] > 'A' && str[i][j] <= 'Z') {
for (int o = i - 1; o >= 1; --o) {
int F = 1;
for (int k = up[i][j]; k <= down[i][j]; ++k) {
if (str[o][k] != '.') {
F = 0;
break;
}
}
if (!F) break;
for (int k = up[i][j]; k <= down[i][j]; ++k) {
str[o][k] = str[i][j] - 'A' + 'a';
}
}
}
}
}
} void gaoD1(char str[][N]) {
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (str[i][j] > 'A' && str[i][j] <= 'Z') {
for (int o = i + 1; o <= n; ++o) {
int F = 1;
for (int k = up[i][j]; k <= down[i][j]; ++k) {
if (str[o][k] != '.') {
F = 0;
break;
}
}
if (!F) break;
for (int k = up[i][j]; k <= down[i][j]; ++k) {
str[o][k] = str[i][j] - 'A' + 'a';
}
}
}
}
}
} void gaoL1(char str[][N]) {
for (int j = 1; j <= m; ++j) {
for (int i = 1; i <= n; ++i) {
if (str[i][j] > 'A' && str[i][j] <= 'Z') {
up[i][j] = j;
for (int o = 1; ; ++o) {
if (j - o < 1) break;
if (str[i][j - o] != '.') break;
up[i][j] = j - o;
str[i][j - o] = str[i][j] - 'A' + 'a';
}
}
}
}
} void gaoR1(char str[][N]) {
for (int j = m; j >= 1; --j) {
for (int i = 1; i <= n; ++i) {
if (str[i][j] > 'A' && str[i][j] <= 'Z') {
down[i][j] = j;
for (int o = 1; ; ++o) {
if (j + o > m) break;
if (str[i][j + o] != '.') break;
down[i][j] = j + o;
str[i][j + o] = str[i][j] - 'A' + 'a';
}
}
}
}
} void print(char str[][N]) {
for (int i = 1; i <= n; ++i) printf("%s\n", str[i] + 1);
} bool ok(char str[][N]) {
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (str[i][j] == '.')
return false;
}
}
return true;
} int main() {
while (scanf("%d %d", &n, &m) != EOF) {
for (int i = 1; i <= n; ++i) {
scanf("%s", str[i] + 1);
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (str[i][j] == 'A') {
ax = i, ay = j;
}
}
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (i == 1) {
if (str[i][j] == '.' || str[i][j] == 'A') up[i][j] = 1;
else up[i][j] = 0;
} else {
if (str[i][j] == '.' || str[i][j] == 'A') up[i][j] = up[i - 1][j] + 1;
else up[i][j] = 0;
}
}
}
for (int i = n; i >= 1; --i) {
for (int j = 1; j <= m; ++j) {
if (i == n) {
if (str[i][j] == '.' || str[i][j] == 'A') down[i][j] = 1;
else down[i][j] = 0;
} else {
if (str[i][j] == '.' || str[i][j] == 'A') down[i][j] = down[i + 1][j] + 1;
else down[i][j] = 0;
}
}
}
// get A size
int Max = -1, Maxl = -1 ,Maxr = -1;
for (int l = 1; l <= m; ++l) {
int MinU = INF, MinD = INF;
for (int r = l; r <= m; ++r) {
MinU = min(MinU, up[ax][r]);
MinD = min(MinD, down[ax][r]);
if (r >= ay && l <= ay) {
if (Max < (r - l + 1) * (MinU + MinD - 1)) {
Maxl = l, Maxr = r, Max = (r - l + 1) * (MinU + MinD - 1);
}
}
}
}
// color A size
gaoA(str, Maxl, Maxr);
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
stra[i][j] = str[i][j];
strb[i][j] = str[i][j];
}
} gaoU(stra);
gaoD(stra);
gaoL(stra);
gaoR(stra); gaoL1(strb);
gaoR1(strb);
gaoU1(strb);
gaoD1(strb); if (ok(strb)) print(strb);
else if (ok(stra)) print(stra);
else assert(0);
}
return 0;
}

Problem M. Managing Difficulties

签到题。

代码:

view code
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 2e3 + 10;
int n, a[N];
unordered_map <int, int> mp; int main() {
int _T; scanf("%d", &_T);
while (_T--) {
mp.clear();
scanf("%d", &n);
for (int i = 1; i <= n; ++i) scanf("%d", a + i);
ll res = 0;
for (int i = n; i >= 1; --i) ++mp[a[i]];
for (int i = 1; i <= n; ++i) {
--mp[a[i]];
for (int j = i - 1; j >= 1; --j) {
int x = 2 * a[i] - a[j];
if (mp.count(x)) {
res += mp[x];
}
}
}
printf("%lld\n", res);
}
return 0;
}

ICPC 2019-2020 North-Western Russia Regional Contest的更多相关文章

  1. 2017 ACM - ICPC Asia Ho Chi Minh City Regional Contest

    2017 ACM - ICPC Asia Ho Chi Minh City Regional Contest A - Arranging Wine 题目描述:有\(R\)个红箱和\(W\)个白箱,将这 ...

  2. ICPC Central Russia Regional Contest (CRRC 19)题解

    题目连接:https://codeforces.com/gym/102780 寒假第二次训练赛,(某菜依旧是4个小时后咕咕咕),战况还行,个人表现极差(高级演员) A:Green tea 暴力枚举即可 ...

  3. 05.24 ICPC 2019-2020 North-Western Russia Regional Contest复现赛+Codeforces Round #645 (Div. 2)

    A.Accurate Movement(复现赛) 题意:两个木块最左边都在0的位置,最右边分别为a,b(b>a),并且短的木条只能在长木条内移动,问两个木条需要移动多少次才能使两个木条的右端都在 ...

  4. 2019-2020 ICPC, NERC, Southern and Volga Russian Regional Contest

    目录 Contest Info Solutions A. Berstagram B. The Feast and the Bus C. Trip to Saint Petersburg E. The ...

  5. 2019-2020 ICPC, NERC, Southern and Volga Russian Regional Contest (Online Mirror, ICPC Rules, Teams Preferred)【A题 类型好题】

    A. Berstagram Polycarp recently signed up to a new social network Berstagram. He immediately publish ...

  6. 2020-2021 ICPC, NERC, Southern and Volga Russian Regional Contest (Online Mirror, ICPC Rules) D. Firecrackers (贪心,二分)

    题意:有个长度为\(n\)的监狱,犯人在位置\(a\),cop在位置\(b\),你每次可以向左或者向右移动一个单位,或者选择不动并在原地放一个爆竹\(i\),爆竹\(i\)在\(s[i]\)秒后爆炸, ...

  7. 2020-2021 ICPC, NERC, Southern and Volga Russian Regional Contest (Online Mirror, ICPC Rules) C. Berpizza (STL)

    题意:酒吧里有两个服务员,每个人每次都只能服务一名客人,服务员2按照客人进酒吧的顺序服务,服务员3按照客人的钱来服务,询问\(q\),\(1\)表示有客人进入酒吧,带着\(m\)块钱,\(2\)表示询 ...

  8. ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Kraków

    ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Kraków Problem A: Rubik’s Rect ...

  9. ACM ICPC 2010–2011, Northeastern European Regional Contest St Petersburg – Barnaul – Tashkent – Tbilisi, November 24, 2010

    ACM ICPC 2010–2011, Northeastern European Regional Contest St Petersburg – Barnaul – Tashkent – Tbil ...

随机推荐

  1. DO、VO、DTO 区别

    DTO:数据传输对象,主要用于外部接口参数传递封装,接口与接口进行传递使用. VO:视图对象,主要用于给前端返回页面参数使用. DO:数据对象,主要用于数据库层传递. DTO转DO:接口接收参数将参数 ...

  2. Dev GridControl 子集合标题

    显示效果: 设置: this.gridView3.OptionsView.ShowViewCaption = true; this.gridView3.ViewCaption = "资产明细 ...

  3. C++复制构造函数,类型转换构造函数,析构函数,引用,指针常量和常量指针

    复制构造函数形如className :: className(const &)   /   className :: className(const className &)后者能以常 ...

  4. Fortify漏洞之Open Redirect(开放式重定向)

    继续对Fortify的漏洞进行总结,本篇主要针对  Open Redirect(开放式重定向)  的漏洞进行总结,如下: 1.1.产生原因: 通过重定向,Web 应用程序能够引导用户访问同一应用程序内 ...

  5. iOS Touch Id 开发

    Touch Id Touch Id是iPhone5S后加入的一项新的功能,也就是大家熟知的指纹识别技术.大家用得最多的可能是手机的解屏操作,不用在和以前一样输入手机的四位数密码进行验证.一方面不用担心 ...

  6. SAP云平台上的ABAP编程环境里如何消费第三方服务

    在ABAP On-Premises环境下,使用ABAP编程消费第三方服务,相信很多ABAP顾问都已经非常熟悉了,无非就是使用CL_HTTP_CLIENT或者CL_REST_HTTP_CLIENT来发送 ...

  7. mysql主从部署

    一.安装环境 1.系统环境 系统 IP 主机名 说明 server_id centos6.7 192.168.0.173 master 数据库:主 173  centos6.7 192.168.0.1 ...

  8. 前端框架开始学习Vue(二)

    1 根据关键字实现数组的过滤 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...

  9. 【ogg三】日常运维篇:清理归档日志,ogg进程注册服务,定期备份数据库

    清理归档日志 ogg使用需要开启归档日志,归档日志会随着时间的推移逐渐增多,占满空间,导致应用无法正常运行. 如果归档日志满了会报错 ORA-00257:archiver error解决办法 检查fl ...

  10. 剖析可执行文件ELF组成

    对比参考:剖析.o文件ELF组成 相比.o的ELF格式,有哪些变化? .rel.text和.rel.data消失了 为什么这两个节会消失? 链接器将各.o中同名的.text和.data节整合到一起时, ...