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. windows下安装mysql-8.0.18-winx64

    1.下载安装包 安装包现在地址: https://dev.mysql.com/downloads/mysql/ 2.解压缩至安装目录 解压缩下载之后的zip,我这里使用的安装路径为: C:\Progr ...

  2. 【转载】Sqlserver存储过程中使用Select和Set给变量赋值

    Sqlserver存储过程是时常使用到的一个数据库对象,在存储过程中会使用到Declare来定义存储过程变量,定义的存储过程变量可以通过Set或者Select等关键字方法来进行赋值操作,使用Set对存 ...

  3. Story of Jerry Wang's Wechat subscription account

    As an SAP Techinical Ambassador,Jerry is always willing to share his SAP expertise to various social ...

  4. ESLint——从零学起

    介绍 ESLint最初是由Nicholas C. Zakas于2013年6月创建的开源项目.它的目标是提供一个插件化的javascript代码检测工具.因此,ESLint就是一个语法规则和代码风格的检 ...

  5. 还想免费继续使用JDK吗?从java11以后别从Oracle下载了

    Java生态系统一直以来是建立在一个高质量的免费(零成本)JDK之上的,它可以从甲骨文(Oracle)和以前的Sun获得. 今天的情况和以前一样. Java现在每六个月发布一次版本,这个版本是指提供带 ...

  6. cdh的web管理界面503

    503 Service Unavailable No server is available to handle this request.       重启 agent  以及 server   

  7. spark 实现多文件输出

    需求 不同的key输出到不同的文件 txt文件 multiple.txt 中国;22 美国;4342 中国;123 日本;44 日本;6 美国;55 美国;43765 日本;786 日本;55 sca ...

  8. 关于MySQL中的锁机制详解

    锁概述 MySQL的锁机制,就是数据库为了保证数据的一致性而设计的面对并发场景的一种规则. 最显著的特点是不同的存储引擎支持不同的锁机制,InnoDB支持行锁和表锁,MyISAM支持表锁. 表锁就是把 ...

  9. PAT基础级-钻石段位样卷2-7-1 心理阴影面积 (5 分)

    这是一幅心理阴影面积图.我们都以为自己可以匀速前进(图中蓝色直线),而拖延症晚期的我们往往执行的是最后时刻的疯狂赶工(图中的红色折线).由红.蓝线围出的面积,就是我们在做作业时的心理阴影面积. 现给出 ...

  10. zookeeper学习(3)----基本结构和命令行操作命令

    一. 数据结构 https://www.jianshu.com/p/8e322462bcca zookeeper存储结构:以树形结构的方式存储数据 ZooKeeper数据模型的结构整体上可以看作是一棵 ...