A. Alex and broken contest

题意

判断一个字符串内出现五个给定的子串多少次。

Code

#include <bits/stdc++.h>
char s[110];
using namespace std;
typedef long long LL;
char* rec[5] = {"Danil", "Olya", "Slava", "Ann", "Nikita"};
int len[5] = {5,4,5,3,6};
bool cmp(char* s1, char* s2, int len) {
for (int i = 0; i < len; ++i) {
if (s1[i] != s2[i]) return false;
}
return true;
}
int main() {
int cnt=0;
scanf("%s", s);
for (int i = 0; s[i]; ++i) {
for (int j = 0; j < 5; ++j) {
if (cmp(rec[j], s+i, len[j])) ++cnt;
}
if (cnt > 2) {printf("NO\n"); return 0;}
}
if (cnt==1) printf("YES\n");
else printf("NO\n");
return 0;
}

B. Nikita and string

题意

给定一个长为\(n(n\leq 5000)\)的只含\('a',b'\)的字符串,先要求删去最少数目的字符,使得留下的字符串可以被分为三截,最左边全\('a'\),中间一段全\('b'\),最右边全\('a'\).

思路

\(O(n^2)\)

预处理前缀和。

枚举两个分界点。

时间复杂度\(O(n^2)\).

\(O(n)\)

\(dp\)做法

参见http://codeforces.com/contest/877/submission/31663633

Code

#include <bits/stdc++.h>
#define maxn 5010
char s[maxn];
int a[maxn], b[maxn];
using namespace std;
typedef long long LL;
int main() {
scanf("%s", s+1);
int len = strlen(s+1);
for (int i = 1; i <= len; ++i) {
a[i] = a[i-1], b[i] = b[i-1];
if (s[i]=='a') ++a[i];
else ++b[i];
}
int ans = len+1;
for (int i = 1; i <= len+1; ++i) {
for (int j = i; j <= len+1; ++j) {
int x1=0, x2=0, x3=0;
if (i > 1) x1 = b[i-1]-b[0];
if (j > i) x2 = a[j-1]-a[i-1];
if (j <= len) x3 = b[len]-b[j-1];
ans = min(ans,x1+x2+x3);
}
}
printf("%d\n", len-ans);
return 0;
}

C. Slava and tanks

题意

有\(1\times n\)的格子,里面不知道哪些位置会有坦克。每架坦克的血量为\(2\). 在位置\(i\)处扔炸弹,该位置的坦克受到一点伤害,并且跑到相邻的格子中去;再受到一次伤害,就死了。问最少扔多少次炸弹能保证消灭所有的坦克,并且输出扔炸弹的序列。

思路

仆の思路

左右两块:两格两格一组地扔;中间:根据%4的值分类讨论。

有点难描述,直接看代码吧Orz

题解

先往所有偶数格子中扔,再往所有奇数格子中扔,最后往所有偶数格子中扔。

证明

1. 可行性:
  1. 先往偶数格子中扔炸弹时,偶数格子中的所有坦克都跑到了奇数格子中;

    此时,只有奇数格子中有坦克,且其中的坦克分为两类:血量为\(1\),血量为\(2\)

  2. 再往奇数格子中扔炸弹,奇数格子中 1) 血量为\(1\)的坦克全都死了; 2) 血量为\(2\)的坦克都跑到了偶数格子中;

    此时,只有偶数格子中有坦克,且其中的坦克只有一类:血量为\(1\)

  3. 最后往偶数格子中扔坦克,全都死了

至于为什么是\(偶\rightarrow 奇\rightarrow 偶\)的顺序而不是\(奇\rightarrow 偶\rightarrow 奇\)的顺序,是因为奇数格子数目\(\geq\)偶数格子数目,所以前者是\(n+n/2\)而后者在\(n\)为奇数时是\(n+n/2+1\).

2. 最优性:

参考题解页面\(ludo\)用户的评论

"

The problem is equivalent to finding a string S such that for all 1 < i ≤ n, i - 1 precedes i somewhere in the string and i precedes i - 1 somewhere in the string.

Now observe that for some i, it occurs either 1 or 2 times in the optimal string. If it is more than 2 times, we can erase the middle ones and obtain a better string.

If for some i, the number of times is 1, then i + 1 must occur (at least) 2 times: to the left of this location and to the right. If i occurs 2 times, then i + 1 must occur (at least) once (in between the two occurences).

From this, you can build the string 2,4,6,... 1,3,5,..., 2,4,6, ... which is therefore optimal.

At every step we get some partial string with all the numbers from 1 to i. Inductively you can show that this is optimal at every transition to i + 1.

"

意思就是说,这个问题等价于找一个串,对于\(1\lt i\leq n\),都有\(i-1\)既在\(i\)之前出现过,也在\(i\)之后出现过。然后在这个转化成的新问题上进行构造。具体见上,就不再翻译了。

转化的依据:当我们轰炸\(i\)位置时,最糟糕的情况是第\(i-1\)个位置和第\(i+1\)个位置上都有坦克。因此,构造出的串中既需要存在\(i,i-1\)这个子串,也需要存在\(i,i+1\)这个子串。换句话说,就是\(i-1\)既在\(i\)之前出现过,也在\(i\)之后出现过。

Code

Ver. 1

#include <bits/stdc++.h>
#define maxn 200010
int ans[maxn];
using namespace std;
typedef long long LL;
int main() {
int n;
scanf("%d", &n);
int tot = 0; printf("%d\n", n+n/2);
for (int i = 1; i <= n/4; ++i) {
ans[tot++] = i*2;
ans[tot++] = i*2-1;
}
for (int i = 1; i <= n/4; ++i) {
ans[tot++] = n-(i*2)+1;
ans[tot++] = n-(i*2)+2;
} if (n%4==1) {
ans[tot++] = n/2+1;
for (int i = 2; i < n; ++i) if (!(i&1)) ans[tot++] = i;
}
else if (n%4==3) {
ans[tot++] = n/2+1, ans[tot++] = n/2, ans[tot++] = n/2+2;
for (int i = 2; i < n; ++i) if (!(i&1)) ans[tot++] = i;
}
else if (n%4==2) {
ans[tot++] = n/2; ans[tot++] = n/2+1, ans[tot++] = n/2;
for (int i = 1; i <= n/4; ++i) ans[tot++] = 2*i, ans[tot++] = n+1-2*i;
}
else {
for (int i = 1; i <= n/4; ++i) ans[tot++] = 2 * i, ans[tot++] = n+1-2*i;
}
printf("%d", ans[0]);
for (int i = 1; i < tot; ++i) printf(" %d", ans[i]); printf("\n"); return 0;
}

Ver. 2

#include <bits/stdc++.h>
#define maxn 200010
int ans[maxn];
using namespace std;
typedef long long LL;
int main() {
int n;
scanf("%d", &n); printf("%d\n", n+n/2); int tot = 0;
for (int i = 1; i <= n; ++i) if (!(i&1)) ans[tot++]= i;
for (int i = 1; i <= n; ++i) if (i&1) ans[tot++] = i;
for (int i = 1; i <= n; ++i) if (!(i&1)) ans[tot++]= i; printf("%d", ans[0]);
for (int i = 1; i < tot; ++i) printf(" %d", ans[i]); printf("\n");
return 0;
}

D. Olya and Energy Drinks

题意

给定一张地图,有些地方有障碍物。给定起始点与终止点,可以向上下左右四个方向走。每秒可至多走\(k\)个单位。问最少花多少时间可以从起点到终点。

思路

裸的\(bfs\)

Code

#include <bits/stdc++.h>
#define maxn 1010
struct node { int x, y; };
int dr[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
char s[maxn];
using namespace std;
typedef long long LL;
bool mp[maxn][maxn];
int v[maxn][maxn];
int main() {
int n, m, k;
scanf("%d%d%d", &n, &m, &k);
for (int i = 1; i <= n; ++i) {
scanf("%s", s+1);
for (int j = 1; j <= m; ++j) {
if (s[j] == '.') mp[i][j] = 0;
else mp[i][j] = 1;
}
}
int x1, y1, x2, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
if (x1==x2&&y1==y2) { puts("0"); exit(0); }
queue<node> q;
while (!q.empty()) q.pop();
q.push({x1,y1});
while (!q.empty()) {
node nd = q.front(); q.pop();
for (int i = 0; i < 4; ++i) {
node temp = nd;
int step = 0;
while (step < k) {
++step;
temp.x += dr[i][0], temp.y += dr[i][1];
if (temp.x <= 0 || temp.x > n || temp.y <= 0 || temp.y > m || mp[temp.x][temp.y]) break;
if (temp.x == x2 && temp.y == y2) { printf("%d\n", v[nd.x][nd.y]+1); exit(0); }
if (!(temp.x==x1&&temp.y==y1) && !v[temp.x][temp.y]) v[temp.x][temp.y] = v[nd.x][nd.y] + 1, q.push({temp.x, temp.y});
}
}
}
printf("-1\n");
return 0;
}

E. Danil and a Part-time Job

题意

给定一棵有根树,根为\(1\),每个点的值是\(0\)或\(1\). 有两种操作,

  1. \(get\ v\):询问以\(v\)为根的子树中有多少个点的值为\(1\);
  2. \(pow\ v\):将以\(v\)为根的子树中所有点的值反转;

思路

\(dfs序+线段树\)

可以说是很裸的题了...

不要脸地来为我原博客里dfs序的文章打下广告_(:з」∠)_ http://blog.csdn.net/kkkkahlua/article/category/7026724

Code

#include <bits/stdc++.h>
#define maxn 200010
#define lson (rt<<1)
#define rson (rt<<1|1)
struct node { int l, r, c, tag; }tr[maxn * 4];
struct Edge { int to, ne; }edge[maxn];
int c[maxn], l[maxn], r[maxn], cnt, tot, ne[maxn];
using namespace std;
typedef long long LL;
void add(int u, int v) {
edge[tot] = {v, ne[u]};
ne[u] = tot++;
}
void dfs(int u) {
l[u] = ++cnt;
for (int i = ne[u]; ~i; i = edge[i].ne) dfs(edge[i].to);
r[u] = cnt;
}
void push_up(int rt) { tr[rt].c = tr[lson].c + tr[rson].c; }
void build(int rt, int l, int r) {
tr[rt].l = l, tr[rt].r = r, tr[rt].tag = 0;
if (l==r) { tr[rt].c = c[l]; return; }
int mid = l+r >> 1;
build(lson, l, mid), build(rson, mid+1, r);
push_up(rt);
}
void push_down(int rt) {
if (tr[rt].tag) {
tr[lson].c = tr[lson].r-tr[lson].l+1-tr[lson].c;
tr[rson].c = tr[rson].r-tr[rson].l+1-tr[rson].c;
tr[lson].tag ^= 1, tr[rson].tag ^= 1;
tr[rt].tag = 0;
}
}
int query(int rt, int l, int r) {
if (tr[rt].l==l && tr[rt].r==r) return tr[rt].c;
push_down(rt);
int mid = tr[rt].l + tr[rt].r >> 1;
if (r <= mid) return query(lson, l, r);
else if (l > mid) return query(rson, l, r);
else return query(lson, l, mid) + query(rson, mid+1, r);
}
void modify(int rt, int l, int r) {
if (tr[rt].l==l && tr[rt].r==r) {
tr[rt].c = tr[rt].r-tr[rt].l+1-tr[rt].c, tr[rt].tag ^= 1;
return;
}
push_down(rt);
int mid = tr[rt].l+tr[rt].r>>1;
if (r<=mid) modify(lson, l, r);
else if (l > mid) modify(rson, l, r);
else modify(lson, l, mid), modify(rson, mid+1, r);
push_up(rt);
}
int main() {
int n, x;
scanf("%d", &n);
memset(ne, -1, sizeof(ne));
for (int i = 2; i <= n; ++i) {
scanf("%d", &x);
add(x, i);
}
dfs(1);
for (int i = 1; i <= n; ++i) {
scanf("%d", &x);
c[l[i]] = x;
}
build(1, 1, n);
int m;
scanf("%d", &m);
char s[5];
while (m--) {
scanf("%s%d", s, &x);
if (s[0]=='g') printf("%d\n", query(1,l[x], r[x]));
else modify(1,l[x], r[x]);
}
return 0;
}

小结

\(D\)和\(E\)这么水...是不是应该以后先看题啊Orz

昨天大半夜构造\(C\)构造了一个多小时...中间还睡着了...还是构造题做得太少。

Codeforces Round #442 Div.2 A B C D E的更多相关文章

  1. Codeforces Round #442 (Div. 2) Danil and a Part-time Job

    http://codeforces.com/contest/877/problem/E 真的菜的不行,自己敲一个模板,到处都是问题.哎 #include <bits/stdc++.h> u ...

  2. Codeforces Round #442 (Div. 2)

    A. Alex and broken contest time limit per test 2 seconds memory limit per test 256 megabytes input s ...

  3. Codeforces Round #442 (Div. 2) E Danil and a Part-time Job (dfs序加上一个线段树区间修改查询)

    题意: 给出一个具有N个点的树,现在给出两种操作: 1.get x,表示询问以x作为根的子树中,1的个数. 2.pow x,表示将以x作为根的子树全部翻转(0变1,1变0). 思路:dfs序加上一个线 ...

  4. Codeforces Round #442 (Div. 2)A,B,C,D,E(STL,dp,贪心,bfs,dfs序+线段树)

    A. Alex and broken contest time limit per test 2 seconds memory limit per test 256 megabytes input s ...

  5. 【Codeforces Round #442 (Div. 2) D】Olya and Energy Drinks

    [链接] 我是链接,点我呀:) [题意] 给一张二维点格图,其中有一些点可以走,一些不可以走,你每次可以走1..k步,问你起点到终点的最短路. [题解] 不能之前访问过那个点就不访问了.->即k ...

  6. 【Codeforces Round #442 (Div. 2) C】Slava and tanks

    [链接] 我是链接,点我呀:) [题意] 有n个位置,每个位置都可能有不定数量的tank; 你每次可以选择一个位置投掷炸弹. 并且,这个位置上的所有tank都会受到你的攻击. 并且失去一点体力. 然后 ...

  7. 【Codeforces Round #442 (Div. 2) B】Nikita and string

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 枚举中间那一段从哪里开始.哪里结束就好 注意为空的话,就全是a. 用前缀和优化一下. [代码] #include <bits/ ...

  8. 【Codeforces Round #442 (Div. 2) A】Alex and broken contest

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 注意是所有的名字里面,只出现了其中某一个名字一次. [代码] #include <bits/stdc++.h> usin ...

  9. Codeforces Round #442 (Div. 2) B题【一道模拟题QAQ】

    B. Nikita and string One day Nikita found the string containing letters "a" and "b&qu ...

随机推荐

  1. CentOS 7 环境下挂载新磁盘

    最近某个项目需要给数据库服务器添加磁盘,由于太久没搞过,就给虚拟机加了10G的空间,用来练习一下磁盘的挂载 一. 首先执行"fdisk -l"命令,查看磁盘信息 [root@loc ...

  2. 嵌入式开发 centos7 交叉编译环境准备

    1. 安装centos7,启动图像化界面. 参考:https://blog.csdn.net/qq_23014435/article/details/74347925 # systemctl get- ...

  3. JAVA解析XML有哪几种方法?并简述各自的优缺点

    DOM: 是用与平台和语言无关的方式表示XML文档的官方W3C标准,分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作.是基于信息层次的 优点有:由于树在内存中是持久的,因此可以修改它以 ...

  4. 笔记-http-header

    笔记-http-header 1.      Requests部分 Host:请求的web服务器域名地址 User-Agent:HTTP客户端运行的浏览器类型的详细信息.通过该头部信息,web服务器可 ...

  5. D3DXCreateTexture

    HRESULT D3DXCreateTexture( __in LPDIRECT3DDEVICE9 pDevice, __in UINT Width, __in UINT Height, __in U ...

  6. Python虚拟机类机制之instance对象(六)

    instance对象中的__dict__ 在Python虚拟机类机制之从class对象到instance对象(五)这一章中最后的属性访问算法中,我们看到“a.__dict__”这样的形式. # 首先寻 ...

  7. 洛谷P1079 Vigenère 密码

    题目链接:https://www.luogu.org/problemnew/show/P1079

  8. msconfig.exe

    msconfig.exe 编辑 本词条缺少概述.名片图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧!   中文名 微软系统配置实用程序 外文名 msconfig.exe 出品者 Micros ...

  9. 使用 Item,ItemManager 在 XNA 中创建物品和道具(十六)

    平方已经开发了一些 Windows Phone 上的一些游戏,算不上什么技术大牛.在这里分享一下经验,仅为了和各位朋友交流经验.平方会逐步将自己编写的类上传到托管项目中,没有什么好名字,就叫 WPXN ...

  10. Form 组件动态绑定数据

    1.Form 组件的作用: a.对用户提交的数据进行验证(form表单/ajax) b.保留用户上次输入的信息 c.可以生成html标签(input表单类的标签) 2..由于form组件中每个字段都是 ...