Contest Info


[Practice Link](https://codeforc.es/contest/1202)

Solved A B C D E F
5/6 Ø Ø Ø Ø Ø -
  • O 在比赛中通过
  • Ø 赛后通过
  • ! 尝试了但是失败了
  • - 没有尝试

Solutions


A. You Are Given Two Binary Strings...

题意:

给出两个数字\(x, y\),令\(f(x)\)为\(x\)的二进制表示,现在要选择一个\(k\)使得\(s_k = f(x) + f(y) \cdot 2^k\)的字典序最小。

思路:

考虑乘上\(2^k\)相当于让\(f(y)\)左移\(k\)位,那么我们肯定要让\(f(y)\)的最后一位\(1\)移到离\(f(x)\)最近的一个\(1\)和它进位之后,这样翻转之后字典序是最小的。

view code

#include <bits/stdc++.h>
using namespace std;

define N 100010

char s[N], t[N]; int main() {

int T; scanf("%d", &T);

while (T--) {

scanf("%s%s", s + 1, t + 1);

int lens = strlen(s + 1);

int lent = strlen(t + 1);

int post = 0;

for (int i = lent; i >= 1; --i) {

if (t[i] == '1') {

post = lent - i;

break;

}

}

int res = 0;

for (int i = lens - post; i >= 1; --i) {

if (s[i] == '1') {

res = lens - post - i;

break;

}

}

printf("%d\n", res);

}

return 0;

}

B. You Are Given a Decimal String...

题意:

有\(x-y\)计数器,它是这样工作的:

  • 初始时数值为\(0\)
  • 给数值加上\(x\)或者\(y\),然后输出数值模\(10\)后的结果
  • 重复第二步操作,直到输出自己满意的序列

    现在给定一段序列,问对于\(x \in [0, 9], y \in [0, 9]\)的\(100\)种计数器,最少需要增加多少数才能使得输出的序列是x-y$计数器合法输出来的?

思路:

考虑对于序列中间隔的两个数\(s[i]\)和\(s[i + 1]\),我们定义它们之间的差值为\((s[i + 1] - s[i] + 10) \% 10\),因为是数值的最后一位,所以它们的真实差距肯定可以写成\(10k + (s[i + 1] - s[i])\),但是我们并不需要关心\(k\)是多少。

我们只需要知道需要多少个\((px + qy) \% 10 = (s[i + 1] - s[i] + 10) \% 10\)。

这个暴力枚举一下\(p, q\)即可,而显然\(p \in [0, 9], q \in [0, 9]\),因为存在模\(10\)操作,\((px + qy) \% 10 = (p \% 10 x + q \% 10 ) \% 10\)

view code

#include <bits/stdc++.h>
using namespace std; const int INF = 0x3f3f3f3f;

const int N = 2e6 + 10;

char s[N];

int n, b[20];

void Min(int &x, int y) {

if (x > y) x = y;

} int main() {

while (scanf("%s", s + 1) != EOF) {

n = strlen(s + 1);

for (int x = 0; x < 10; ++x) {

for (int y = 0; y < 10; ++y) {

for (int k = 0; k < 10; ++k) b[k] = INF;

for (int p = 0; p < 10; ++p) {

for (int q = 0; q < 10; ++q) if (p | q) {

Min(b[(p * x + q * y) % 10], p + q - 1);

}

}

int ans = 0;

for (int i = 1; i < n; ++i) {

int t = (s[i + 1] - s[i] + 10) % 10;

if (b[t] == INF) {

ans = -1;

break;

}

ans += b[t];

}

printf("%d%c", ans, " \n"[y == 9]);

}

}

}

return 0;

}

C. You Are Given a WASD-string...

题意:

有一个机器人,现在给出一系列行走步骤,问能否在任意处添加一个步骤,使得它的行动范围尽量小。

行动范围的定义为用一个最小的矩形框住它的行动路径。范围即为矩形的面积。

思路:

将横竖分开考虑,如果可以缩小行动范围,那么必然是长缩短一或者宽缩短一。

我们考虑什么时候边长可以缩短一:

  • 考虑从一个位置插入一个状态,那么考虑从从这个点之后的所有这个方向的路径都会整体往上移动一个或者往下移动一个
  • 那么判断一下这个移动是否有效即可。
  • 有效的定义为这个点之后的路径的最值比这个点以及之前的最值大,这样它的最值才会减一,不然的话这个点以及之前的最值仍然掌控着矩形边界
view code

#include <bits/stdc++.h>
using namespace std;

define ll long long

define N 200010

char s[N]; int main() {

int T; scanf("%d", &T);

while (T--) {

scanf("%s", s + 1);

int n = strlen(s + 1);

int nowx = 0, nowy = 0;

int up = 0, down = 0, left = 0, right = 0;

int gup = 0, gdown = 0, gleft = 0, gright = 0;

for (int i = 1; i <= n; ++i) {

if (s[i] == 'W') --nowx;

if (s[i] == 'S') ++nowx;

if (s[i] == 'A') --nowy;

if (s[i] == 'D') ++nowy;

up = min(up, nowx);

down = max(down, nowx);

left = min(left, nowy);

right = max(right, nowy);

gup = max(gup, nowx - up);

gdown = max(gdown, down - nowx);

gleft = max(gleft, nowy - left);

gright = max(gright, right - nowy);

}

ll x[2], y[2];

x[0] = max(gup, gdown);

x[1] = max(1ll * (gup || gdown), x[0] - (gup != gdown));

y[0] = max(gleft, gright);

y[1] = max(1ll * (gleft || gright), y[0] - (gleft != gright));

printf("%lld\n", min((x[0] + 1) * (y[1] + 1), (x[1] + 1) * (y[0] + 1)));

}

return 0;

}

D. Print a 1337-string...

题意:

构造一个序列,这个序列只包含\(\{1, 3, 7\}\),并且一共有\(n\)的子序列是\(1337\)

思路:

考虑最后一位放\(7\)。

然后放\(x\)个\(3\)。

那么每放一个\(1\)可以产生\([1, \frac{x(x - 1)}{2}]\)个\(1337\)。

那么考虑从大到小贪心放即可,总能放完。

view code

#include <bits/stdc++.h>
using namespace std;

define ll long long

define N 100010

ll n;

ll f(ll x) {

return x * (x - 1) / 2;

} int main() {

int T; scanf("%d", &T);

while (T--) {

scanf("%lld", &n);

for (int i = 32000; i >= 2; --i) {

while (f(i) <= n) {

n -= f(i);

putchar('1');

}

putchar('3');

}

assert(n == 0);

puts("37");

}

return 0;

}

E. You Are Given Some Strings...

题意:

给出一个文本串\(T\),和若干个模式串\(S_i\),定义\(f(t, s)\)为\(s\)在\(t\)中出现的次数。

计算下式:

\[\begin{eqnarray*}
\sum\limits_{i = 1}^n \sum\limits_{j = 1}^n f(t, s_i + s_j)
\end{eqnarray*}
\]

思路:

考虑\(T\)对整体的贡献,即使\(T\)中存在多少个子串,使得可以从某个中间位置切开,使得左右两边都是模式串。

那么枚举这个中间位置即可,做两边\(AC\)自动机,求出\(f[i], g[i]\),分别表示以\(i\)结尾的模式串匹配次数和以\(i\)开头的模式串匹配次数。

那么乘一乘即是结果。

view code

#include <bits/stdc++.h>
using namespace std;

define ll long long

define N 200010

int n;

string s[N], t, tr;

ll f[N], g[N];

define ALP 26

struct ACAM {

struct node {

int nx[ALP], fail;

int cnt;

node() {

memset(nx, -1, sizeof nx);

cnt = 0;

}

}t[N];

int root, tot;

int que[N], ql, qr;

//节点从1开始

int newnode() {

++tot;

t[tot] = node();

return tot;

}

void init() {

tot = 0;

root = newnode();

}

void insert(string s) {

int len = s.size();

int now = root;

for (int i = 0; i < len; ++i) {

if (t[now].nx[s[i] - 'a'] == -1)

t[now].nx[s[i] - 'a'] = newnode();

now = t[now].nx[s[i] - 'a'];

}

++t[now].cnt;

}

void build() {

ql = 1, qr = 0;

t[root].fail = root;

for (int i = 0; i < ALP; ++i) {

if (t[root].nx[i] == -1) {

t[root].nx[i] = root;

} else {

t[t[root].nx[i]].fail = root;

que[++qr] = t[root].nx[i];

}

}

while (ql <= qr) {

int now = que[ql++];

t[now].cnt += t[t[now].fail].cnt;

for (int i = 0; i < ALP; ++i) {

if (t[now].nx[i] == -1) {

t[now].nx[i] = t[t[now].fail].nx[i];

}

else {

t[t[now].nx[i]].fail = t[t[now].fail].nx[i];

que[++qr] = t[now].nx[i];

}

}

}

}

void query(string s, ll *f) {

int len = s.size();

int now = root;

for (int i = 0; i < len; ++i) {

now = t[now].nx[s[i] - 'a'];

f[i] = t[now].cnt;

}

}

}ac; int main() {

ios::sync_with_stdio(false);

cin.tie(0); cout.tie(0);

while (cin >> t) {

tr = t; reverse(tr.begin(), tr.end());

cin >> n;

ac.init();

for (int i = 1; i <= n; ++i) cin >> s[i], ac.insert(s[i]);

ac.build();

ac.query(t, f);

ac.init();

for (int i = 1; i <= n; ++i) {

reverse(s[i].begin(), s[i].end());

ac.insert(s[i]);

}

ac.build();

ac.query(tr, g);

ll res = 0;

int len = t.size();

reverse(g, g + len);

for (int i = 0; i < len - 1; ++i) {

res += f[i] * g[i + 1];

}

cout << res << "\n";

}

return 0;

}

Educational Codeforces Round 70的更多相关文章

  1. Educational Codeforces Round 70 (Rated for Div. 2)

    这次真的好难...... 我这个绿名蒟蒻真的要崩溃了555... 我第二题就不会写...... 暴力搜索MLE得飞起. 好像用到最短路?然而我并没有学过,看来这个知识点又要学. 后面的题目赛中都没看, ...

  2. Educational Codeforces Round 70 题解

    噩梦场. 题目出奇的难,好像一群外国老哥看 A 看着看着就哭了-- A 找到 \(b\) 最低的 \(1\),这个 \(1\) 肯定要跟 A 中的一个 \(1\) 搭配,而且是能搭配的 \(1\) 中 ...

  3. n=C(2,n)+k(构造)( Print a 1337-string)Educational Codeforces Round 70 (Rated for Div. 2)

    题目链接:https://codeforc.es/contest/1202/problem/D 题意: 给你一个数 n ( <=1e9 ),让你构造137713713.....(只含有1,3,7 ...

  4. (模拟)关于进制的瞎搞---You Are Given a Decimal String...(Educational Codeforces Round 70 (Rated for Div. 2))

    题目链接:https://codeforc.es/contest/1202/problem/B 题意: 给你一串数,问你插入最少多少数可以使x-y型机器(每次+x或+y的机器,机器每次只取最低位--% ...

  5. Educational Codeforces Round 70 (Rated for Div. 2) 题解

    比赛链接:https://codeforc.es/contest/1202 A. You Are Given Two Binary Strings... 题意:给出两个二进制数\(f(x)\)和\(f ...

  6. [Educational Codeforces Round 16]E. Generate a String

    [Educational Codeforces Round 16]E. Generate a String 试题描述 zscoder wants to generate an input file f ...

  7. [Educational Codeforces Round 16]D. Two Arithmetic Progressions

    [Educational Codeforces Round 16]D. Two Arithmetic Progressions 试题描述 You are given two arithmetic pr ...

  8. [Educational Codeforces Round 16]C. Magic Odd Square

    [Educational Codeforces Round 16]C. Magic Odd Square 试题描述 Find an n × n matrix with different number ...

  9. [Educational Codeforces Round 16]B. Optimal Point on a Line

    [Educational Codeforces Round 16]B. Optimal Point on a Line 试题描述 You are given n points on a line wi ...

随机推荐

  1. 剪贴板神器:Ditto

    ditto – 善用佳软 免费开源的 Windows 管理剪贴板,让你处理文字更高效:Ditto - 少数派

  2. Spring Boot使用@Value注解获取配置文件中的属性

    获取配置文件的内容——

  3. 音视频入门-07-认识YUV

    * 音视频入门文章目录 * YUV & YCbCr 简介 YUV,是一种颜色编码方法.常使用在各个视频处理组件中. YUV 在对照片或视频编码时,考虑到人类的感知能力,允许降低色度的带宽. Y ...

  4. 使用Dockerfile构建镜像并push到私有仓库

    环境:OS X 10.10.5 maven 3.3.9 Docker version 1.12.2 docker-machine version 0.8.2 程序示例为http://www.cnblo ...

  5. 【SoloPi】SoloPi使用3-性能测试-启动时间测试

    响应耗时计算工具Soloπ响应耗时计算工具,通过录屏分帧的方式自动识别起始点和结束点,精确计算耗时. 特性模拟用户视觉,计算结果更贴近用户体验自动记录点击起始点,自动识别屏幕变化结束点通过OpenCV ...

  6. ASP.NET Core 2.1 中的 HttpClientFactory (Part 1) HttpClientFactory介绍

    原文:https://www.stevejgordon.co.uk/introduction-to-httpclientfactory-aspnetcore  发表于:2018年1月 ASP.NET ...

  7. Go net/http,web server

    net/http 包实现 HTTP Server Go 中,实现一个最简单的 http server 非常容易,代码如下: package main import ( "fmt" ...

  8. 数据结构之链表(LinkedList)(一)

    链表(Linked List)介绍 链表是有序的列表,但是它在内存中是存储如下 1)链表是以节点方式存储的,是链式存储 2)每个节点包含data域(value),next域,指向下一个节点 3)各个节 ...

  9. goroutine并发控制与通信

    转发:https://mp.weixin.qq.com/s/ZlyQHfmoY1lzOoRgFSCOBw 开发go程序的时候,时常需要使用goroutine并发处理任务,有时候这些goroutine是 ...

  10. flutter入门之常见的flutter问题汇总(转)

    1. 使用AppBar后如何去掉左边的返回箭头.左边的图标对应的是leading,源代码如下(吐槽一下,CSDN暂不支持dart语言): Widget leading = widget.leading ...