zoukankan      html  css  js  c++  java
  • BZOJ 3790 神奇项链(manacher+贪心)

    3790: 神奇项链

    Time Limit: 10 Sec  Memory Limit: 64 MB

    Description

    母亲节就要到了,小 H 准备送给她一个特殊的项链。这个项链可以看作一个用小写字
    母组成的字符串,每个小写字母表示一种颜色。为了制作这个项链,小 H 购买了两个机器。第一个机器可以生成所有形式的回文串,第二个机器可以把两个回文串连接起来,而且第二个机器还有一个特殊的性质:假如一个字符串的后缀和一个字符串的前缀是完全相同的,那么可以将这个重复部分重叠。例如:aba和aca连接起来,可以生成串abaaca或 abaca。现在给出目标项链的样式,询问你需要使用第二个机器多少次才能生成这个特殊的项链。 

    Input

    输入数据有多行,每行一个字符串,表示目标项链的样式。 

    Output

    多行,每行一个答案表示最少需要使用第二个机器的次数。 

    Sample Input

    abcdcba
    abacada
    abcdef

    Sample Output

    0
    2
    5

    HINT

    每个测试数据,输入不超过 5行 
    每行的字符串长度小于等于 50000

    题解

    先用manacher算出每一个位置的最大回文半径,再算出每一个点对应的回文区间。

    然后就是一个用最少区间覆盖整个区间的贪心。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<algorithm>
     6 using namespace std;
     7 const int N=200000;
     8 char s[N],str[N];
     9 int len,p[N];
    10 struct Line{
    11     int l,r;
    12 }c[N];
    13 void init(){
    14     str[0]=str[1]='#';
    15     for(int i=1;i<=len;i++){
    16         str[i<<1]=s[i];
    17         str[(i<<1)+1]='#';
    18     }
    19     len=(len<<1)+1;
    20 }
    21 void manacher(){
    22     int mx=0,id;
    23     for(int i=1;i<=len;i++){
    24         if(mx>i)p[i]=min(p[id-(i-id)],p[id]+id-i);
    25         else p[i]=1;
    26         while(str[i+p[i]]==str[i-p[i]])p[i]++;
    27         if(i+p[i]>mx){
    28             id=i;
    29             mx=i+p[i];
    30         }
    31     }
    32 }
    33 bool cmp(Line a,Line b){
    34     return a.l<b.l;
    35 }
    36 void work(){
    37     sort(c+1,c+1+len,cmp);
    38     int now=1,tmp=0,ans=0;
    39     for(int i=1;i<=len;i++){
    40         if(c[i].l<=now){
    41             tmp=max(tmp,c[i].r);
    42         }
    43         else{
    44             now=tmp+1;
    45             if(now>len)break;
    46             ans++;
    47             i--;
    48         }
    49     }
    50     printf("%d
    ",ans);
    51 }
    52 int main(){
    53     while(scanf("%s",s+1)!=EOF){
    54         len=strlen(s+1);
    55         init();
    56         manacher();
    57         for(int i=1;i<=len;i++){
    58             c[i].l=i-p[i]+1;
    59             c[i].r=i+p[i]-1;
    60         }
    61         work();
    62     }
    63     return 0;
    64 }
  • 相关阅读:
    根据IP地址查找MAC地址
    MongoDB导入导出以及数据库备份
    本地mongodb数据库导出到远程数据库中
    datatable自动增加序号
    IDEA出现无法加载主类
    远程连接本地mongodb 数据库
    js将后台传入得时间格式化
    Java蓝桥杯--基础练习 (6)回文数
    Java蓝桥杯--基础练习(5)杨辉三角形
    Java蓝桥杯--基础练习(4)查找整数
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9547035.html
Copyright © 2011-2022 走看看