https://vjudge.net/contest/175596#overview

A.设第i次出现的位置左右端点分别为Li,Ri

初始化L0 = 0,则有ans = sum{ (L[i] - L[i-1]) * (n + 1 - Ri) }

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5
 6 using namespace std;
 7
 8 int last = 0;
 9
10 char s[5010];
11
12 long long ans;
13
14 int main() {
15     scanf("%s", s + 1);
16     int n = strlen(s + 1);
17     for(int i = 1;i <= n;i ++) {
18         if(i + 3 <= n && s[i] == 'b' && s[i + 1] == 'e' && s[i + 2] == 'a' && s[i + 3] == 'r') {
19             ans += 1ll * (i - last) * (n + 1 - i - 3);
20             last = i;
21             i += 3;
22         }
23     }
24     cout << ans;
25     return 0;
26 }

View Code

B.AC自动机板子题,我的板子常数很大

 1 #include <queue>
 2 #include <cstdio>
 3 #include <cstring>
 4
 5 using namespace std;
 6
 7 const int maxn = 500010;
 8
 9 struct trie {
10     int next[maxn][26], fail[maxn], end[maxn];
11     int L, root;
12     queue <int> q;
13
14     int newnode() {
15         for(int i = 0;i < 26;i ++)
16             next[L][i] = -1;
17         end[L] = 0;
18         return L ++;
19     }
20
21     void clear() {
22         L = 0;
23         root = newnode();
24     }
25
26     int idx(char c) {
27         return c - 'a';
28     }
29
30     void insert(char *buf) {
31         int len = strlen(buf), now = root, c;
32         for(int i = 0;i < len;i ++) {
33             c = idx(buf[i]);
34             if(next[now][c] == -1)
35                 next[now][c] = newnode();
36             now = next[now][c];
37         }
38         end[now] ++;
39     }
40
41     void build() {
42         for(int i = 0;i < 26;i ++) {
43             if(next[root][i] == -1)
44                 next[root][i] = root;
45             else {
46                 fail[next[root][i]] = root;
47                 q.push(next[root][i]);
48             }
49         }
50         while(!q.empty()) {
51             int now = q.front();
52             q.pop();
53             for(int i = 0;i < 26;i ++) {
54                 if(next[now][i] == -1)
55                     next[now][i] = next[fail[now]][i];
56                 else {
57                     fail[next[now][i]] =  next[fail[now]][i];
58                     q.push(next[now][i]);
59                 }
60             }
61         }
62     }
63
64     int query(char *buf) {
65         int len = strlen(buf), now = root, res = 0, tmp;
66         for(int i = 0;i < len;i ++) {
67             tmp = now = next[now][idx(buf[i])];
68             while(tmp != root) {
69                 res += end[tmp];
70                 end[tmp] = 0;
71                 tmp = fail[tmp];
72             }
73         }
74         return res;
75     }
76 };
77
78 trie ac;
79
80 int Case, n;
81
82 char buf[1000010];
83
84 int main() {
85     scanf("%d", &Case);
86     while(Case --) {
87         scanf("%d", &n), ac.clear();
88         while(n --) scanf("%s", buf), ac.insert(buf);
89         scanf("%s", buf), ac.build();
90         printf("%d\n", ac.query(buf));
91     }
92     return 0;
93 }

View Code

C.考察对KMP中next数组的理解,由一个串重复而来

所以就是max(i - next[i])

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4
 5 using namespace std;
 6
 7 char s[1000010];
 8
 9 int nex[1000010];
10
11 int main() {
12     int i, j, ans, len;
13     while(~scanf("%s", s)) {
14         len = strlen(s);
15         nex[0] = -1;
16         ans = 0;
17         for(i = 1;i < len;i ++) {
18             j = nex[i - 1];
19             while(j >= 0 && s[j + 1] != s[i]) j = nex[j];
20             if(s[j + 1] == s[i]) {
21                 nex[i] = j + 1;
22                 ans = max(ans, i - nex[i]);
23             }
24             else nex[i] = -1, ans = max(ans, i + 1);
25         }
26         printf("%d\n", ans);
27     }
28     return 0;
29 }

View Code

D.令a[i] -= a[i + 1],题目就变成了

求数列中出现次数不小于2次的最长重复子串

后缀数组一个典型问题,二分子串长度即可

(考场上观察了半天手里板子的接口...然后放弃了)

E.先假设要由空串刷成串2,区间DP即可

dp[i][j]代表把 i-j 这段刷成串2需要的最少次数

可能分成几段分开去刷,所以不能直接ans = dp[L][R] (s1[L] != s2[L],s1[R] != s2[R])

利用f[i]代表 1-i 这段由串1刷成串2的最少次数

ans = f[n]

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4
 5 using namespace std;
 6
 7 int n, dp[110][110], f[110];
 8
 9 char s1[110], s2[110];
10
11 int main() {
12     while(~scanf("%s %s", s1 + 1, s2 + 1)) {
13         n = strlen(s1 + 1);
14         memset(dp, 0x3f, sizeof dp);
15         for(int d = 1;d <= n;d ++)
16             for(int i = 1;i + d - 1 <= n;i ++) {
17                 int j = i + d - 1;
18                 if(i == j) dp[i][i] = 1;
19                 else if(j == i + 1) dp[i][j] = 2 - (s2[i] == s2[j]);
20                 else {
21                     for(int k = i;k < j;k ++)
22                         dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j] - (s2[i] == s2[k + 1]));
23                 }
24             }
25         for(int i = 1;i <= n;i ++) {
26             f[i] = dp[1][i];
27             if(s1[i] == s2[i]) f[i] = min(f[i - 1], f[i]);
28             else
29                 for(int j = 1;j < i;j ++)
30                     f[i] = min(f[i],  f[j] + dp[j + 1][i]);
31         }
32         printf("%d\n", f[n]);
33     }
34     return 0;
35 }

View Code

F.简单的字典树

 1 #include <cstdio>
 2 #include <cstring>
 3
 4 const int maxn = 6000010;
 5
 6 struct trie {
 7     int ch[maxn][2];
 8     int val[maxn];
 9     int siz;
10
11     void init() {
12         siz = 1;
13         memset(ch, 0, sizeof ch);
14         memset(val, 0, sizeof val);
15     }
16
17     void insert(int x) {
18         int i, u, c;
19         int num[40] = {0};
20         for(i = 0;i < 30;i ++)
21             num[i] = x & (1 << i);
22         for(i = u = 0;i < 30;i ++) {
23             c = (num[29 - i] != 0);
24             if(!ch[u][c]) ch[u][c] = siz ++;
25             u = ch[u][c], val[u] ++;
26         }
27         val[0] ++;
28     }
29
30     void de1ete(int x) {
31         int i, u, c;
32         int num[40] = {0};
33         for(i = 0;i < 30;i ++)
34             num[i] = x & (1 << i);
35         for(i = u = 0;i < 30;i ++) {
36             u = ch[u][(num[29 - i] != 0)];
37             val[u] --;
38         }
39         val[0] --;
40     }
41
42     void query(int x) {
43         int i, u, c, ans = 0;
44         int num[40] = {0};
45         for(i = 0;i < 30;i ++)
46             num[i] = x & (1 << i);
47         for(i = u = 0;i < 30;i ++) {
48             c = !(num[29 - i] != 0);
49             if(ch[u][c] && val[ch[u][c]]) ans |= (1 << (29 - i)), u = ch[u][c];
50             else u = ch[u][!c];
51         }
52         printf("%d\n", ans);
53     }
54 };
55
56 trie now;
57
58 int n, x;
59
60 char str[5];
61
62 int main() {
63     now.init();
64     now.insert(0);
65     scanf("%d", &n);
66     while(n --) {
67         scanf("%s %d", str, &x);
68         switch(str[0]) {
69             case '+':now.insert(x);break;
70             case '-':now.de1ete(x);break;
71             case '?':now.query(x);break;
72         }
73     }
74     return 0;
75 }

View Code

G.

H.

I.

J.

K.最长回文子串,直接上马拉车

板子不长,mp[i] - 1 表示以 i 为中心的最长回文串长度

 1 #include <map>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5
 6 using namespace std;
 7
 8 const int maxn = 1000010;
 9
10 char str[3], s[maxn], ma[maxn], ans[maxn];
11
12 int mp[maxn], l, len;
13
14 map <char, char> p;
15
16 void manacher() {
17     l = 0;
18     ma[l ++] = '$';
19     ma[l ++] = '#';
20     for(int i = 0;i < len;i ++)
21         ma[l ++] = s[i], ma[l ++] = '#';
22     ma[l] = 0;
23     int mx = 0, id = 0;
24     for(int i = 0;i < l;i ++) {
25         mp[i] = mx > i ? min(mp[2 * id - i], mx - i) : 1;
26         while(ma[i + mp[i]] == ma[i - mp[i]]) mp[i] ++;
27         if(i + mp[i] > mx) mx = i + mp[i], id = i;
28     }
29 }
30
31 int main() {
32     while(~scanf("%s %s", str, s)) {
33         len = strlen(s);
34         manacher();
35         int leng = 0, pos = -1;
36         for(int i = 0;i < l;i ++)
37             if(mp[i] > leng)
38                 leng = mp[i], pos = i;
39         leng --;
40         if(leng == 1) {
41             puts("No solution!");
42             continue;
43         }
44         if(pos & 1) {
45             printf("%d %d\n", pos / 2 - leng / 2, pos / 2 - leng / 2 + leng - 1);
46             for(int i = pos / 2 - leng / 2, j = 1;j <= leng;i ++, j ++)
47                 ans[j] = s[i];
48         }
49         else {
50             printf("%d %d\n", pos / 2 - leng / 2 - 1, pos / 2 - leng / 2 + leng - 2);
51             for(int i = pos / 2 - leng / 2 - 1, j = 1;j <= leng;i ++, j ++)
52                 ans[j] = s[i];
53         }
54         ans[leng + 1] = 0;
55         int dis = 'a' - str[0];
56         for(int i = 0;i < 26;i ++)
57             p['a' + i] = 'a' + (i + dis + 26) % 26;
58         for(int i = 1;i <= leng;i ++)
59             ans[i] = p[ans[i]];
60         puts(ans + 1);
61     }
62     return 0;
63 }

View Code

L.变换同D题,然后就是裸的KMP了

 1 #include <map>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5
 6 using namespace std;
 7
 8 const int maxn = 1000010;
 9
10 char str[3], s[maxn], ma[maxn], ans[maxn];
11
12 int mp[maxn], l, len;
13
14 map <char, char> p;
15
16 void manacher() {
17     l = 0;
18     ma[l ++] = '$';
19     ma[l ++] = '#';
20     for(int i = 0;i < len;i ++)
21         ma[l ++] = s[i], ma[l ++] = '#';
22     ma[l] = 0;
23     int mx = 0, id = 0;
24     for(int i = 0;i < l;i ++) {
25         mp[i] = mx > i ? min(mp[2 * id - i], mx - i) : 1;
26         while(ma[i + mp[i]] == ma[i - mp[i]]) mp[i] ++;
27         if(i + mp[i] > mx) mx = i + mp[i], id = i;
28     }
29 }
30
31 int main() {
32     while(~scanf("%s %s", str, s)) {
33         len = strlen(s);
34         manacher();
35         int leng = 0, pos = -1;
36         for(int i = 0;i < l;i ++)
37             if(mp[i] > leng)
38                 leng = mp[i], pos = i;
39         leng --;
40         if(leng == 1) {
41             puts("No solution!");
42             continue;
43         }
44         if(pos & 1) {
45             printf("%d %d\n", pos / 2 - leng / 2, pos / 2 - leng / 2 + leng - 1);
46             for(int i = pos / 2 - leng / 2, j = 1;j <= leng;i ++, j ++)
47                 ans[j] = s[i];
48         }
49         else {
50             printf("%d %d\n", pos / 2 - leng / 2 - 1, pos / 2 - leng / 2 + leng - 2);
51             for(int i = pos / 2 - leng / 2 - 1, j = 1;j <= leng;i ++, j ++)
52                 ans[j] = s[i];
53         }
54         ans[leng + 1] = 0;
55         int dis = 'a' - str[0];
56         for(int i = 0;i < 26;i ++)
57             p['a' + i] = 'a' + (i + dis + 26) % 26;
58         for(int i = 1;i <= leng;i ++)
59             ans[i] = p[ans[i]];
60         puts(ans + 1);
61     }
62     return 0;
63 }

View Code

转载于:https://www.cnblogs.com/ytytzzz/p/7275492.html

bupt summer training for 16 #8 ——字符串处理相关推荐

  1. bupt summer training for 16 #2 ——计算几何

    https://vjudge.net/contest/171368#overview A.一个签到题,用叉积来判断一个点在一条线的哪个方向 可以二分,数据范围允许暴力 1 #include <c ...

  2. bupt summer training for 16 #3 ——构造

    https://vjudge.net/contest/172464 后来补题发现这场做的可真他妈傻逼 A.签到傻逼题,自己分情况 1 #include <cstdio> 2 #includ ...

  3. bupt summer training for 16 #5 ——数据结构

    https://vjudge.net/contest/173780 A.假设 Pt = i,则由Ppi = i得 Ppt = t = Pi 所以就有 if Pt = i then Pi = t 1 # ...

  4. 2020 BUPT Winter Training #1 Div.1

    2020 BUPT Winter Training #1 Div.1 这些题真的很不错 读完题一道都不会 补完每一道都骂自己sb 文章目录 [A - Cover it!](https://vjudge ...

  5. Python天天美味(16) - 过滤字符串的技巧,map与itertools.imap

    Python中的map函数非常有用,在字符转换和字符遍历两节都出现过,现在,它又出现了,会给我们带来什么样的惊喜呢?是不是要告诉我们,map是非常棒的,以后要多找它玩呢? 具体的实例 我们需要在目录中 ...

  6. 算法 64式 16、字符串算法整理

    1算法思想 2 字符串系列 类别-编号 题目 来源 1 替换空格 请事先一个函数,把字符串中的每个空格替换成"%20".例如 例如 输入: We are happy. 输出: We ...

  7. python3 16位字符串16进制字符串转整形问题

    碰到的这段字符串为一个ip地址,想要转换为整形 ,用int直接转失败 str="240E098099000000" python2中有long类型 python3中没有long类型 ...

  8. [部分学校JAVAmooc答题解答] 16版.字符串算法

    1.实验要求 本实验要求:根据用户输入的字符串,计算字符:"sh"重复出现的次数. 1-1. 创建工程并配置环境: 1-1.1. 限制1. 工程取名:SE_JAVA_EXP_E02 ...

  9. Luat number数字十进制转16十六进制字符串

    pack loacl str = pack.pack("b", number) pack 库支持将一系列数据按照格式字符转化为 lua 字符串或者将 lua 字符串按照格式字符转化 ...

最新文章

  1. linux系统目录结构介绍
  2. mongodb jar包_MongoDB是什么?看完你就知道了!
  3. POJ 2187 Beauty Contest( 凸包求最远点对 )
  4. Zabbix Linux 客户端安装
  5. jquery 样式获取设置值_[JQuery] jQuery选择器ID、CLASS、标签获取对象值、属性、设置css样式...
  6. java代码中何处以main开始_自测题: Java 基础
  7. caffe使用训练好的模型对自己的一张图片进行测试
  8. 百度SEO站群流光风格个人主页HTML源码
  9. 微软全球AI负责人沈向洋博士:下一个智能终端的风口 | IoT in Action
  10. oops程序是什么意思_OOPS中的抽象是什么?
  11. zb_system login.php,zblog后台登录地址怎么修改?
  12. CXF WebService 教程
  13. 使用下面的方法有利于提高JS代码的执行效率
  14. AutoCAD2012从入门到精通中文视频教程 第13课 正多边形(个人收藏)
  15. win10插上耳机还外放(win10插上耳机还外放怎么设置)
  16. 梦雨百度网盘机器人好友群组消息自动回复软件(可用于自动发货场景)
  17. 谷歌浏览器好用的复制粘贴插件_关于谷歌浏览器(chrome)的一些好用的插件推荐...
  18. java校验特殊字符_java 中文及特殊字符校验
  19. 电子计算机技术人才需求,电子与信息技术专业人才需求调研报告.pdf
  20. 记一次生产数据库事故

热门文章

  1. springboot 1.5.2 集成kafka 简单例子
  2. 2017.3.22-morning
  3. 李宁-2015年7月13日-个人文档
  4. Android用户界面程序设计示例
  5. tslib1.4安装小记
  6. 360 linux 扩展文件夹,360签具名工Linux下载0907 官方版
  7. java 面试 概率论_编程培训-115个Java面试题和答案B.pdf
  8. ps里面怎么插入流程图_学会这3个方法,5分钟能绘制出好看又高级的流程图
  9. 微型计算机系统包括( )几部分,微型计算机系统包括哪几个部分?
  10. MySQL的IFNULL() 函数使用