ICPC 2019-2020 North-Western Russia Regional Contest
Contest Info
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的更多相关文章
- 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\)个白箱,将这 ...
- ICPC Central Russia Regional Contest (CRRC 19)题解
题目连接:https://codeforces.com/gym/102780 寒假第二次训练赛,(某菜依旧是4个小时后咕咕咕),战况还行,个人表现极差(高级演员) A:Green tea 暴力枚举即可 ...
- 05.24 ICPC 2019-2020 North-Western Russia Regional Contest复现赛+Codeforces Round #645 (Div. 2)
A.Accurate Movement(复现赛) 题意:两个木块最左边都在0的位置,最右边分别为a,b(b>a),并且短的木条只能在长木条内移动,问两个木条需要移动多少次才能使两个木条的右端都在 ...
- 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 ...
- 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 ...
- 2020-2021 ICPC, NERC, Southern and Volga Russian Regional Contest (Online Mirror, ICPC Rules) D. Firecrackers (贪心,二分)
题意:有个长度为\(n\)的监狱,犯人在位置\(a\),cop在位置\(b\),你每次可以向左或者向右移动一个单位,或者选择不动并在原地放一个爆竹\(i\),爆竹\(i\)在\(s[i]\)秒后爆炸, ...
- 2020-2021 ICPC, NERC, Southern and Volga Russian Regional Contest (Online Mirror, ICPC Rules) C. Berpizza (STL)
题意:酒吧里有两个服务员,每个人每次都只能服务一名客人,服务员2按照客人进酒吧的顺序服务,服务员3按照客人的钱来服务,询问\(q\),\(1\)表示有客人进入酒吧,带着\(m\)块钱,\(2\)表示询 ...
- 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 ...
- 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 ...
随机推荐
- ES6语法基本使用
什么是ES6? ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了.Mozilla公司将在这个标准的基础上,推出JavaScript 2. ...
- stm32f103re stop模式下降低功耗
一端口设置1.将N.C的GPIO统一配置为GPIO_Mode_AIN: 2.检查输入引脚,按照不工作时候的状态相应配置为 IPD/IPU,即避免在内部上/下拉电阻上消耗电流,而且该电流理论值为VCC ...
- 【SoloPi】SoloPi使用4-功能使用,一机多控
Soloπ是什么Soloπ是一个无线化.非侵入式的Android自动化工具,公测版拥有录制回放.性能测试.一机多控三项主要功能,能为测试开发人员节省宝贵时间. 一机多控功能Soloπ支持通过操作一台主 ...
- POJ1861(Network)-Kruskal
题目在这 Sample Input 4 6 1 2 1 1 3 1 1 4 2 2 3 1 3 4 1 2 4 1 Sample Output 1 4 1 2 1 3 2 3 3 4 题目意思:4个点 ...
- cell上的按钮点击和左滑冲突
cell上的某个按钮的点击事件,当cell左滑的时候,只要活动的区域也在按钮上,那么按钮的点击事件也会调用. fix: 给按钮添加一个手势(TapGesture)那么当点击的时候就会响应点击手势的方法 ...
- 九、分组查询详解(group by & having)
本篇内容 分组查询语法 聚合函数 单字段分组 多字段分组 分组前筛选数据 分组后筛选数据 where和having的区别 分组后排序 where & group by & having ...
- L ==> E · L · K
三剑客:Elastic Stack 在学习ELK前,先对 Lucene作基本了解. 今天才知道关系型数据库的索引是 B-Tree,罪过... 减少磁盘寻道次数 ---> 提高查询性能 Lucen ...
- -bash: 无法为立即文档创建临时文件: 设备上没有空间---记一次报错
故障发生原因 测试环境,之前用该机器做过docker-compose,后来有需要用到该机器上的docker环境,需要将旧的docker容器全部删除,由于之前启动是使用docker-compose启动的 ...
- Computer Vision_33_SIFT:A novel coarse-to-fine scheme for automatic image registration based on SIFT and mutual information——2014
此部分是计算机视觉部分,主要侧重在底层特征提取,视频分析,跟踪,目标检测和识别方面等方面.对于自己不太熟悉的领域比如摄像机标定和立体视觉,仅仅列出上google上引用次数比较多的文献.有一些刚刚出版的 ...
- 【DRF框架】利用序列化组件操作
使用序列化组件进行操作 不带参数:查+增 带参数:查.改.删 不带参数的操作 # url路由 url(r'^book_list/$',Search_book.as_view()), # views.p ...