UVA 11475 Extend to Palindrome (kmp || manacher || 后缀数组)
来源:互联网 发布:java 制作图片 编辑:程序博客网 时间:2024/06/05 10:53
题目链接:点击打开链接
题意:给你一个串,让你在串后面添加尽可能少的字符使得这个串变成回文串。
思路:这题可以kmp,manacher,后缀数组三种方法都可以做,kmp和manacher效率较高,时间复杂度是O(n),后缀数组时间复杂度是O(nlogn).思路是求出元串的后缀和反串的前缀匹配的最大长度。用后缀数组的时候求出l=lcp(i,len+1),判断l+i是不是等于len,如果等于那么就是结果。
kmp:
#include<iostream>#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#include<vector>#include<map>#include<set>#include<string>#include<bitset>#include<algorithm>using namespace std;#define lson th<<1#define rson th<<1|1typedef long long ll;typedef long double ldb;#define inf 99999999#define pi acos(-1.0)#define maxn 1000600char s1[maxn],s2[maxn];int nextt[maxn],len;int pd(char *s1,char *s2){ int i,j,len1,len2; len1=len2=len; i=0;j=-1; memset(nextt,-1,sizeof(nextt)); while(i<len2){ if(j==-1 || s2[i]==s2[j]){ i++; j++; nextt[i]=j; } else j=nextt[j]; } i=0;j=0; int ans=1; while(i<len1 && j<len2){ if(j==-1 || s1[i]==s2[j]){ //ans=max(ans,j+1); 注意这句不能加,因为要求的是当i=len1时候,串二最大匹配了多少长度 i++; j++; } else j=nextt[j]; //这里要解释一下,这里的意思是s[i]和s[j]不匹配了,那么看前j个字符前缀和后缀匹配的程度,注意,这里前j个字符是s[0]...s[j-1] } ans=j; return ans;}int main(){ int n,m,i,j,ans; while(scanf("%s",s1)!=EOF) { strcpy(s2,s1); len=strlen(s1); reverse(s2,s2+len); ans=pd(s1,s2); printf("%s",s1); for(i=len-1-ans;i>=0;i--){ printf("%c",s1[i]); } printf("\n"); } return 0;}
manacher:
#include<iostream>#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#include<vector>#include<map>#include<set>#include<string>#include<bitset>#include<algorithm>using namespace std;#define lson th<<1#define rson th<<1|1typedef long long ll;typedef long double ldb;#define inf 99999999#define pi acos(-1.0)#define maxn 100060char s[maxn],ss[maxn*2]; //要开两倍大小int p[maxn*2];int main(){ int n,m,i,j,mx,idx,maxx,len,len1; while(scanf("%s",s)!=EOF) { len=strlen(s); len1=len; ss[0]='$'; ss[1]='#'; for(i=0;i<len;i++){ ss[i*2+2]=s[i]; ss[i*2+3]='#'; } mx=0;maxx=0; len=2*len+2; int ans=inf; for(i=1;i<len;i++){ if(mx>i){ //这里的mx为满足条件的后一个,这样如果i<=idx+p[i]-1就能比较了 p[i]=min(p[idx*2-i],mx-i); } else p[i]=1; while(ss[i+p[i]]==ss[i-p[i]]){ p[i]++; } if(maxx<p[i])maxx=p[i]; if(mx<i+p[i]){ //这里更新的mx也是范围内的后一个 mx=i+p[i]; idx=i; } if(i+p[i]-1==len-1 ){ //printf("--->%d\n",i); ans=min(ans,(i-(p[i]-1)) /2 ); } } printf("%s",s); for(i=ans-1;i>=0;i--){ printf("%c",s[i]); } printf("\n"); //printf("%d\n",ans); } return 0;}
后缀数组:
#include<iostream>#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#include<vector>#include<map>#include<set>#include<string>#include<bitset>#include<algorithm>using namespace std;#define lson th<<1#define rson th<<1|1typedef long long ll;typedef long double ldb;#define inf 99999999#define pi acos(-1.0)#define M 100050#define maxn 200050char s1[M],s2[M];int a[maxn];int idx(char c){ if(c>='a' && c<='z')return c-'a'+1; if(c>='A' && c<='Z')return c-'A'+1+26;}int sa[maxn];int wa[maxn],wb[maxn],wv[maxn],we[maxn];int rk[maxn],height[maxn];int cmp(int *r,int a,int b,int l){ return r[a]==r[b]&&r[a+l]==r[b+l];}void build_sa(int *r,int n,int m){ int i,j,p,*x=wa,*y=wb,*t; for(i=0;i<m;i++)we[i]=0; for(i=0;i<n;i++)we[x[i]=r[i]]++; for(i=1;i<m;i++)we[i]+=we[i-1]; for(i=n-1;i>=0;i--)sa[--we[x[i]]]=i; for(j=1,p=1;p<n;j*=2,m=p){ for(p=0,i=n-j;i<n;i++)y[p++]=i; for(i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j; for(i=0;i<n;i++)wv[i]=x[y[i]]; for(i=0;i<m;i++)we[i]=0; for(i=0;i<n;i++)we[wv[i]]++; for(i=1;i<m;i++)we[i]+=we[i-1]; for(i=n-1;i>=0;i--)sa[--we[wv[i]]]=y[i]; for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; }}void calheight(int *r,int n){ int i,j,k=0; for(i=1;i<=n;i++)rk[sa[i]]=i; for(i=0;i<n;height[rk[i++] ]=k){ for(k?k--:0,j=sa[rk[i]-1];r[i+k]==r[j+k];k++); }}int minx[200100][30];void init_rmq(int n){ int i,j; for(i=1;i<=n;i++)minx[i][0]=height[i]; for(j=1;j<=20;j++){ for(i=1;i<=n;i++){ if(i+(1<<j)-1<=n) { minx[i][j]=min(minx[i][j-1],minx[i+(1<<(j-1))][j-1]); } } }}int lcp(int l,int r){ int k,i; l=rk[l];r=rk[r]; if(l>r)swap(l,r); l++; k=(log((r-l+1)*1.0)/log(2.0)); return min(minx[l][k],minx[r-(1<<k)+1][k]);}int main(){ int n,m,i,j,len,l; while(scanf("%s",s1)!=EOF) { strcpy(s2,s1); len=strlen(s1); reverse(s2,s2+len); n=0; for(i=0;i<len;i++){ a[n++]=idx(s1[i]); } a[n++]=55; for(i=0;i<len;i++){ a[n++]=idx(s2[i]); } a[n]=0; build_sa(a,n+1,60); calheight(a,n); init_rmq(n); for(i=0;i<len;i++){ l=lcp(i,len+1); if(i+l==len)break; } printf("%s",s1); for(i=len-1-l;i>=0;i--){ printf("%c",s1[i]); } printf("\n"); } return 0;}
0 0
- UVA 11475 Extend to Palindrome (kmp || manacher || 后缀数组)
- UVA 11475 Extend to Palindrome KMP,后缀数组
- Extend to Palindrome - UVa 11475 Manacher算法
- UVA - 11475 Extend to Palindrome manacher+贪心
- UVA 11475 Extend to Palindrome 后缀数组 LCP
- UVA 11475 - Extend to Palindrome(KMP)
- uva 11475 - Extend to Palindrome(KMP)
- UVA 11475 Extend to Palindrome KMP
- Uva 11475 : Extend to Palindrome(Hash或KMP)
- UVA-11475-Extend to Palindrome((扩展)kmp)
- UVa 11475 - Extend to Palindrome
- Extend to Palindrome - UVa 11475 哈希
- UVa 11475-Extend to Palindrome JAVA
- UVA 11475 Extend to Palindrome hash
- uva11475 - Extend to Palindrome KMP
- UVA 11475 Extend to Palindrome(字符hash)
- 后缀数组 hihocoder 1084 Extend KMP
- (CDOJ) UESTC 606 Palindrome Again 后缀数组二分 + Manacher + Hash
- java语言的跨平台型原理
- POJ 1364King (差分约束 + spfa (bellman) 判环)
- 深入Java单例模式
- UML六种关系
- 天梯-排序
- UVA 11475 Extend to Palindrome (kmp || manacher || 后缀数组)
- 算法学习笔记之约瑟夫环问题
- Android学习笔记3:使用日志工具
- 《剑指offer》01 赋值运算符函数
- Android基础:动画三:属性动画
- sicily 1047(数学)
- ZOJ - 3875 Lunch Time (模拟)水
- c++写windows服务程序
- Android学习笔记4:探究活动1