kuangbin专题16H(next数组)

题目链接: https://vjudge.net/contest/70325#problem/H

题意: 输入字符串 str, 求 str 子串中既是 str 前缀又是 str 后缀的的字符串长度, 按照升序输出.

思路: 先求个 next 数组, next[i] 为以 i - 1(字符串下标从0开始) 字符为后缀的字符串与以第一个字符为前缀的字符串的最大匹配长度.

首先 str 本身是满足条件的. 然后再不断用 next[len] 迭代 len 即可. len 的初始值为 str 的长度. 由 next 的性质可以知道以 next[len] - 1 为后缀的字符串会和以 len - 1 为后缀的字符串重合, 那么所有迭代到的子串都会和以 str 最后一个字符为后缀的字符串重合. (可以参考下面的图) 那么现在前后缀条件都满足啦.

图是从 http://www.cnblogs.com/dongsheng/archive/2012/08/13/2636261.html偷过来的....

代码:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 using namespace std;
 5
 6 const int MAXN = 4e5 + 10;
 7 int nxt[MAXN], vis[MAXN], len;
 8 char str[MAXN];
 9
10 void get_nxt(void){
11     memset(nxt, 0, sizeof(nxt));
12     int i = 0, j = -1;
13     nxt[0] = -1;
14     while(i < len){
15         if(j == -1 || str[i] == str[j]) nxt[++i] = ++j;
16         else j = nxt[j];
17     }
18 }
19
20 int main(void){
21     while(~scanf("%s", str)){
22         len = strlen(str);
23         int cnt = 0;
24         get_nxt();
25         vis[cnt++] = len;
26         while(nxt[len] > 0){
27             len = nxt[len];
28             vis[cnt++] = len;
29         }
30         for(int i = cnt - 1; i >= 0; i--){
31             printf("%d", vis[i]);
32             if(i) printf(" ");
33         }
34         puts("");
35     }
36     return 0;
37 }

时间: 2024-08-08 21:58:07

kuangbin专题16H(next数组)的相关文章

kuangbin专题四 : 最短路 I 题 Arbitrage

kuangbin专题四 : 最短路 I 题  Arbitrage POJ 2240 Arbitrage is the use of discrepancies in currency exchange rates to transform one unit of a currency into more than one unit of the same currency. For example, suppose that 1 US Dollar buys 0.5 British pound,

kuangbin专题专题四 Til the Cows Come Home POJ - 2387

题目链接:https://vjudge.net/problem/POJ-2387 题意:从编号为n的城市到编号为1的城市的最短路. 思路:dijkstra模板题,直接套板子,代码中我会带点注释给初学者看. 1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <cstdio> 5 #include <string> 6 using namespac

【kuangbin专题】计算几何基础(极角相关)

[POJ 1696] Space Ants [题目大意] 给定多个点,对他们按照下面的规则排序,每个都在前一个点组成的左边,并且连线不相交(典型如图) [题目分析] 不断进行极角排序,不断选取一定区域内最符合要求的解 [代码] 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #define ll double 5 using namespace std; 6 const double eps

kuangbin专题 专题九 连通图 HDU 4738 Caocao&#39;s Bridges

题目链接:https://vjudge.net/problem/HDU-4738 题目:tarjan求桥,坑点: 题目说是分岛任务...如果所有岛之间没有完全连通,就不需要执行任务了...答案直接是0... 桥上可能没人,但是,炸弹需要一个人去送,所以至少1个人. 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 6 const int N

[算法专题] 二分搜索&amp;排序数组

基础知识 二分非递归写法: int binary_search(const int a[], const int size, const int val) { int lower = 0; int upper = size-1; /* invariant: if a[i]==val for any i, then lower <= i <= upper */ while (lower <= upper) { int i = lower + (upper-lower)>>1;

kuangbin专题七、线段树

题意:线段树,单点更新,区间查询 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 7 const int maxn=5e4+5; 8 int sum[maxn*4]; //sum求和,开四倍空间 9 int num[maxn]; //存原数组下标[1,n] 10 11 //up更新节点信息,这里是求和

kuangbin专题总结一 简单搜索

A - 棋盘问题:在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C. 解题思路:DFS,在这里有两个搜索方向,同时对每个位置的描述由xy坐标完成,第一次我尝试使用pair+vector保存棋盘位置,用两个数组描述放过棋子的行和列但是由于清除标记没做好WA了.这里是因为DFS搜索中状态转移没确定好,导致清楚标记复杂而出错,改为逐行递归逐列遍历.在这里

kuangbin专题十二 基础DP1【从入门到熟练】【9+1题】

HDU1024 Max Sum Plus Plus 感觉这题是整个系列里难度最高的题之一? #include<bits/stdc++.h> #include<stdio.h> #include<iostream> #include<algorithm> #include<cstring> #include<map> #include<vector> #define inf 2e9 #define maxnode 20000

kuangbin专题十六 KMP&amp;&amp;扩展KMP HDU1711 Number Sequence

Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1], b[2], ...... , b[M] (1 <= M <= 10000, 1 <= N <= 1000000). Your task is to find a number K which make a[K] = b[1], a[K + 1] = b[2], ...... , a[K + M - 1] = b[M]. If there are