洛谷 P3426 [POI2005]SZA-Template

本文介绍了一个关于寻找字符串中最短重复模式的问题,通过构建模板并利用next数组来确定能够完整覆盖目标字符串的最短重复序列长度,实现时间和空间效率的优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

括弧,这是一个错误的做法,并不能AC

题目描述

Byteasar wants to put a rather long pattern on his house. In order to do this, he has to prepare an appropriate template with letters cut off first. He is going to put the pattern on the wall by putting the pattern on the wall in the appropriate place and painting over it. This way he can "print" all the letters that are on the template at one time (it is not possible to "print" only some of them). It is, however, possible, to paint some letters on the wall several times, as a result of different applications of the template. The letters on the template are adjacent (there are no spaces on it). Of course, it is possible to prepare a template with the whole pattern on it. But Byteasar would like to minimize the cost, so he wants to make a template as short as possible.

TaskWrite a programme that:

reads from the standard input the pattern Byteasar wants to put on his house,determines the minimal length of the template needed to do it,writes the result to the standard output.

Byteasar 想在墙上涂一段很长的字符,他为了做这件事从字符的前面一段中截取了一段作为模版. 然后将模版重复喷涂到相应的位置后就得到了他想要的字符序列.一个字符可以被喷涂很多次,但是一个位置不能喷涂不同的字符.做一个模版很费工夫,所以他想要模版的长度尽量小,求最小长度是多少.拿样例来说 ababbababbabababbabababbababbaba , 模版为前8个字符ababbaba, 喷涂的过程为: ababbababbabababbabababbababbaba

输入输出格式

输入格式:

 

In the first and only line of the standard input there is one word. It is the pattern Byteasar wants painted on his house. It consists of no more than  and no less than  lower-case (non-capital) letters of the English alphabet.

 

输出格式:

 

In the first and only line of the standard output one integer should be written - the minimal number of letters in the template.

 

输入输出样例

输入样例#1:
ababbababbabababbabababbababbaba
输出样例#1:
8

显然通过nxt我们可以找出所有可能的长度,然后从小到大枚举可以拿90分耶!
 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <string>
 6 #include <cstring>
 7 #include <cmath>
 8 #include <map>
 9 #include <stack>
10 #include <set>
11 #include <vector>
12 #include <queue>
13 #include <time.h>
14 #define eps 1e-7
15 #define INF 0x3f3f3f3f
16 #define MOD 1000000007
17 #define rep0(j,n) for(int j=0;j<n;++j)
18 #define rep1(j,n) for(int j=1;j<=n;++j)
19 #define pb push_back
20 #define set0(n) memset(n,0,sizeof(n))
21 #define ll long long
22 #define ull unsigned long long
23 #define iter(i,v) for(edge *i=head[v];i;i=i->nxt)
24 #define print_runtime printf("Running time:%.3lfs\n",double(clock())/1000.0)
25 #define TO(j) printf(#j": %d\n",j)
26 //#define OJ
27 using namespace std;
28 const int MAXINT = 500010;
29 const int MAXNODE = 100010;
30 const int MAXEDGE = 2*MAXNODE;
31 char BUF,*buf;
32 int read(){
33     char c=getchar();int f=1,x=0;
34     while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
35     while(isdigit(c)){x=x*10+c-'0';c=getchar();}
36     return f*x;
37 }
38 char get_ch(){
39     char c=getchar();
40     while(!isalpha(c)) c=getchar();
41     return c;
42 }
43 //------------------- Head Files ----------------------//
44 int nxt[MAXINT];
45 char s[MAXINT];
46 vector<int> t;
47 void getnxt(){
48     int l = strlen(s);
49     int k=0;
50     for(int i=1;i<l;i++){
51         for(;s[i]!=s[k]&&k;k=nxt[k-1]);
52         if(s[i]==s[k]) k++;
53         nxt[i]=k;
54     }
55 }
56 int test(int len){
57     int l = strlen(s),lpos=-1,k=0;
58     rep0(i,l){
59         for(;s[i]!=s[k]&&k;k=nxt[k-1]);
60         if(s[i]==s[k]) k++;
61         if(k==len) lpos = i,k=nxt[k-1];
62         if(i-lpos>=len) return 0;
63     }
64     return 1;
65 }
66 void get_input();
67 void work();
68 int main() {
69     get_input();
70     work();
71     return 0;
72 }
73 void work(){
74     int l = strlen(s);
75     getnxt();
76     int k = nxt[l-1];
77     while(k){
78         t.push_back(k);
79         k=nxt[k-1];
80     }
81     for(int i=t.size()-1;i>=0;i--){
82         if(t.size()>=1000&&t[i]<=10000) continue;
83         if(test(t[i])) {printf("%d\n",t[i]);return ;}
84     }
85     printf("%d\n",l);
86 }
87 void get_input(){
88     scanf("%s",s);
89 }
少女骗分中

 

转载于:https://www.cnblogs.com/LoveYayoi/p/7010125.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值