zoukankan      html  css  js  c++  java
  • Manacher练习

    K:

    题意:求回文串。

    思路:Manacher算法模版题

     1 #include <stdio.h>
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <stdbool.h>
     5 #include <stdlib.h>
     6 #include <string>
     7 #include <string.h>
     8 #include <math.h>
     9 #include <vector>
    10 #include <queue>
    11 #include <stack>
    12 #include <set>
    13 #include <map>
    14 
    15 #define INF 0x3f3f3f3f
    16 #define LL long long
    17 #define MAXN 1000005
    18 using namespace std;
    19 
    20 char Ma[MAXN*2];
    21 int Mp[MAXN*2];
    22 char s[MAXN];
    23 
    24 void Manacher(char s[],int len)
    25 {
    26     int l = 0;
    27     Ma[l++] = '$';
    28     Ma[l++] = '#';
    29     for (int i=0;i<len;i++)
    30     {
    31         Ma[l++] = s[i];
    32         Ma[l++] = '#';
    33     }
    34     Ma[l++] = 0;
    35     int mx = 0;
    36     int id = 0;
    37     for (int i=0;i<l;i++)
    38     {
    39         Mp[i] = mx>i?min(Mp[2*id-i],mx-i):1;
    40         while (Ma[i+Mp[i]] == Ma[i-Mp[i]])
    41             Mp[i]++;
    42         if (i+Mp[i]>mx)
    43         {
    44             mx = Mp[i]+i;
    45             id = i;
    46         }
    47     }
    48 }
    49 
    50 int main()
    51 {
    52     ios_base::sync_with_stdio(0);
    53     cin.tie(NULL);
    54     //freopen("../in.txt","r",stdin);
    55     int t = 1;
    56     while (cin >> s) {
    57         if (strcmp(s,"END") == 0)
    58             break;
    59         int len = strlen(s);
    60         Manacher(s, len);
    61         int ans = 0;
    62         for (int i = 0; i < 2 * len + 2; i++)
    63             ans = max(ans, Mp[i] - 1);
    64         printf("Case %d: %d
    ",t++,ans);
    65     }
    66     return 0;
    67 }
    Ackerman

    L:

    思路:在Manacher算法中判断是否增加回文长度的时候多判断下是否满足左边升序右边降序即可

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 #define ll long long int 
     8 #define ull unsigned long long int 
     9 #define e 2.718281828459
    10 #define INF 0x7fffffff
    11 #pragma warning(disable:4996)
    12 #define pf printf
    13 #define sf scanf
    14 #define max(a,b) (a)>(b)?(a):(b);
    15 #define min(a,b) (a)<(b)?(a):(b);
    16 #define pi  acos(-1.0);
    17 #define  eps 1e-9;
    18 #include <cstdlib>
    19 using namespace std;
    20 
    21 
    22 
    23 int n;
    24 int ar[100005];
    25 int temp[200010];
    26 int p[200010];
    27 int manacher(int len) {
    28     int i, j ;
    29     int mid=0;
    30     int ans = 0;
    31     int mx = 0;
    32     p[0] = 1;
    33     for (i = 1; i <= len; i++) {
    34         j = 2 * mid - i;//j和i关于mid对称
    35         if (i >= mx) p[i] = 1;//超出一位,一个字符,赋值1
    36         else p[i] = min(p[j], mx - i);//二者中小的那一个,若 mx - i>p[j],说明i+回文长度未超过mx, mx - i<p[j],则说明i+p[i]回文长度超过了mx,回文只能取到mx-i然后手动匹配
    37 
    38                                       //不论超出与否,手动匹配,i超出或不超出都手动匹一下
    39         while (temp[i - p[i]] == temp[i + p[i]]&&temp[i+p[i]-2]>=temp[i+p[i]])// i - p[i]>=1&&i+p[i]<=len 被省去,因为temp[0]和temp[len]不同
    40             p[i]++;
    41 
    42         if (i + p[i] > mx) {
    43             mx = i + p[i];//更新mx让它尽量远移
    44             mid = i;//更新中点mid
    45         }
    46         ans=ans > p[i] ? ans : p[i];//记录最大回文长度
    47     }
    48 
    49 
    50     return ans;
    51 }
    52 
    53 void init(int len) {
    54     temp[0] = -1;//第一位加-1防止溢出
    55     temp[1] =-1;
    56     int i,j;
    57 
    58     for (i = 2, j = 0; j < len; j++) {
    59         temp[i++] = ar[j];
    60         temp[i++] = -1;
    61     }
    62     temp[i] = -2;//最后一位防止溢出,注意要和第一位的值不同,这样在匹配时才可省去溢出判断
    63 }
    64 
    65 int main(void) {
    66     int t;
    67     sf("%d", &t);
    68     while (t--) {
    69         sf("%d",&n);
    70         for (int i = 0; i < n; i++)  sf("%d", &ar[i]);
    71         init(n);
    72         int maxlen = manacher(2 * n + 1);//2*n+1:除去最头和最尾
    73         pf("%d
    ", maxlen-1);
    74 
    75     }
    76     return 0;
    77 }
    Ackerman

    M:

    题意:输入格式 :字符(ch) +空格+字符串(s)。要先将s进行转换。ch要转换为'a',其他字符也要相应变化,比如ch='b'时。那么'b'就要转换为’a'。‘c'就要转换为 'b','d'要转换为'c',....,'a'要转换为'z'。简单来说,就要s中的每个字母要发生一定的偏移。题目要求转换后的s的最长回文子串的起始和终止位置,并输出子串,如果有多个则输出第一个。如果没有,就输出''No solution!''

    思路:首先先对字符串进行转化,然后之后就是Manacher算法。这题的难点我觉得是在记录左右位置的地方。

     1 #include <stdio.h>
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <stdbool.h>
     5 #include <stdlib.h>
     6 #include <string>
     7 #include <string.h>
     8 #include <math.h>
     9 #include <vector>
    10 #include <queue>
    11 #include <stack>
    12 #include <set>
    13 #include <map>
    14 
    15 #define INF 0x3f3f3f3f
    16 #define LL long long
    17 #define MAXN 200005
    18 using namespace std;
    19 
    20 char Ma[MAXN*2];
    21 int Mp[MAXN*2];
    22 char s[MAXN];
    23 int cnt;
    24 int middle;
    25 
    26 void Manacher(char s[],int len)
    27 {
    28     cnt = 0;
    29     int l = 0;
    30     Ma[l++] = '$';
    31     Ma[l++] = '#';
    32     for (int i=0;i<len;i++)
    33     {
    34         Ma[l++] = s[i];
    35         Ma[l++] = '#';
    36     }
    37     Ma[l++] = 0;
    38     int mx = 0;
    39     int id = 0;
    40     for (int i=0;i<l;i++)
    41     {
    42         Mp[i] = mx>i?min(Mp[2*id-i],mx-i):1;
    43         while (Ma[i+Mp[i]] == Ma[i-Mp[i]])
    44             Mp[i]++;
    45         if (i+Mp[i]>mx)
    46         {
    47             mx = Mp[i]+i;
    48             id = i;
    49         }
    50         if (Mp[i]-1>cnt){
    51             cnt = Mp[i]-1;
    52             middle = i;
    53         }
    54     }
    55 }
    56 
    57 int main()
    58 {
    59     ios_base::sync_with_stdio(0);
    60     cin.tie(NULL);
    61     char c;
    62     while (cin >> c)
    63     {
    64         middle = 0;
    65         cin >> s;
    66         int len = strlen(s);
    67         int dis = c-'a';
    68         for (int i=0;i<len;i++)
    69         {
    70             s[i] = (s[i]-'a'-dis+26)%26+'a';
    71         }
    72         Manacher(s,len);
    73         if (cnt == 1)
    74             cout << "No solution!" << endl;
    75         else
    76         {
    77             int l = middle-cnt+1;
    78             int r = middle+cnt-1;
    79             cout << l/2-1 << " " << r/2-1 << endl;
    80             for (int i=l;i<=r;i++)
    81             {
    82                 if (Ma[i] == '#' || Ma[i] == '$')
    83                     continue;
    84                 else
    85                     cout << Ma[i];
    86             }
    87             cout << endl;
    88         }
    89     }
    90     return 0;
    91 }
    Ackerman
  • 相关阅读:
    为什么要用Hibernate框架? 把SessionFactory,Session,Transcational封装成包含crud的工具类并且处理了事务,那不是用不着spring了?
    Weblogic12c安装与配置详解
    淘宝自己的前端框架KISSY(类似jquery)
    ExtJS4中initComponent和constructor的区别
    Servlet的getContextPath(), getServletPath(), getRequestURI(), getRealPath("/")
    Hash Join 一定是选择小表作为驱动表吗
    oracle for loop 简单
    oracle正则表达式
    Android开发--用户定位服务--UserLocation
    android蓝牙开发---与蓝牙模块进行通信
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/11286191.html
Copyright © 2011-2022 走看看