ZOJ3296 —Connecting the Segments
一道很有意思的题目,活用了最长回文子串算法Manacher算法和最少区间覆盖。
最少区间覆盖:其实就是把一堆一小段区间按左边排序,区间数sum=0;然后把其中覆盖进(1,n)的区间中,开始先找其实为1的区间,找到最远的点t,找到一次,区间数sum加1,
把t赋值给tt,在把1值t,然后就不断循环找出一个区间起始点在【t+2,tt+1】的区间,找到能延伸到最远的一点tt‘,然后把tt赋值给t,然后把tt’赋值给tt,每找到一次区间数sum就加1,然后继续循环。直到tt=n位置就结束,得到最少区间数。好吧,我也感觉我说不明白= =,还是建议你百度一下吧。
Manacher算法:百度就有了。
题目传送门:http://acm.zju.edu.cn/onlinejudge/showRuns.do?contestId=1&problemCode=3296&judgeReplyIds=5
题目意思:给你一个字符串,然后让你用这个字符串处理出来的回文串,拼接成之前给出的字符串,求最少的拼接次数。
做法:先用Manacher算法处理出回文子串的区间,然后用最少区间覆盖,得出最少区间覆盖的值-1就可以得出最少拼接数。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define M 100050 char str1[M],str[2*M]; int rad[M],nn,n; struct st { int s,t; }a[100010]; int cmp(const st &b,const st &c) { if(b.s<c.s) { return 1; } return 0; } void Manacher(int *rad,char *str,int n) { int i; int mx = 0; int id; for(i=1; i<n; i++) { if( mx > i ) rad[i] = rad[2*id-i]<mx-i?rad[2*id-i]:mx-i; else rad[i] = 1; for(; str[i+rad[i]] == str[i-rad[i]]; rad[i]++) ; if( rad[i] + i > mx ) { mx = rad[i] + i; id = i; } } } int main() { int i,ans,Case=1,j; while(scanf("%s",str1)!=EOF) { nn=strlen(str1); n=2*nn+2; str[0]='$'; for(i=0;i<=nn;i++) { str[2*i+1]='#'; str[2*i+2]=str1[i]; } // printf("%s\n",str); Manacher(rad,str,n); ans=1; int k=0;
//处理出回文子串区间。 for(i=2;i<=n;i++) { rad[i]--; //printf("%d %d %c\n",i,rad[i],str[i]); if(rad[i]==0) continue; if(str[i]=='#') { if((rad[i])%2==1) { a[++k].s=(i-(rad[i]))/2; a[k].t=(i+(rad[i]))/2; } else { a[++k].s=(i-(rad[i])+1)/2; a[k].t=(i+(rad[i])-1)/2; } } else if(str[i]>='a'&&str[i]<='z') { if((rad[i])%2==0) { a[++k].s=(i-(rad[i]))/2; a[k].t=(i+(rad[i]))/2; } else { a[++k].s=(i-(rad[i])+1)/2; a[k].t=(i+(rad[i])-1)/2; } } } /*for(i=1;i<=k;i++) { printf("%d %d \n",a[i].s,a[i].t); }*/
//以下为最少区间覆盖。 sort(a+1,a+k+1,cmp); int end=0,sta=1,sum=1; i=1; while(i<=k&&a[i].s==sta) { if(a[i].t>end) end=a[i].t; i++; } while(end!=nn) { sta=end+1; j=end; while(i<=k&&a[i].s<=sta) { if(a[i].t>j) j=a[i].t; i++; } end=j; sum++; } printf("%d\n",sum-1); } return 0; }