• Bazinga(HDU5510+KMP)


    t题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5510

    题目:

    题意:找到一个编号最大的字符串满足:存在一个编号比它小的字符串不是它的字串。

    思路:KMP。但是这题的复杂度极大,杭电服务器跑稳T,我还试了一发-_-||。想了很久想到一个玄学优化,我们首先比较相邻的两个字符串,假设为i和i-1,且i-1是i的字串,那么如果某个大编号包含i则必然包含i-1,此时就没有必要再和i-1跑一边KMP了。如下图所示:

    代码实现如下:

     1 #include <set>
     2 #include <map>
     3 #include <queue>
     4 #include <stack>
     5 #include <cmath>
     6 #include <bitset>
     7 #include <cstdio>
     8 #include <string>
     9 #include <vector>
    10 #include <cstdlib>
    11 #include <cstring>
    12 #include <iostream>
    13 #include <algorithm>
    14 using namespace std;
    15 
    16 typedef long long ll;
    17 typedef pair<ll, ll> pll;
    18 typedef pair<ll, int> pli;
    19 typedef pair<int, ll> pil;;
    20 typedef pair<int, int> pii;
    21 typedef unsigned long long ull;
    22 
    23 #define lson i<<1
    24 #define rson i<<1|1
    25 #define bug printf("*********
    ");
    26 #define FIN freopen("D://code//in.txt", "r", stdin);
    27 #define debug(x) cout<<"["<<x<<"]" <<endl;
    28 #define IO ios::sync_with_stdio(false),cin.tie(0);
    29 
    30 const double eps = 1e-8;
    31 const int mod = 10007;
    32 const int maxn = 2000 + 7;
    33 const double pi = acos(-1);
    34 const int inf = 0x3f3f3f3f;
    35 const ll INF = 0x3f3f3f3f3f3f3f;
    36 
    37 int t, n;
    38 int nex[507][maxn], len[507], vis[507];
    39 char s[507][maxn];
    40 
    41 void get_next(int x) {
    42     nex[x][1] = 0;
    43     for(int i = 2, j = 0; i <= len[i]; i++) {
    44         while(j > 0 && s[x][i] != s[x][j+1]) j = nex[x][j];
    45         if(s[x][i] == s[x][j+1]) j++;
    46         nex[x][i] = j;
    47     }
    48 }
    49 
    50 bool kmp(int x, int y) {
    51     for(int i = 1, j = 0; i <= len[x]; i++) {
    52         while(j > 0 && (j == len[y] || s[x][i] != s[y][j+1])) j = nex[y][j];
    53         if(s[x][i] == s[y][j+1]) j++;
    54         if(j == len[y]) {
    55             return true;
    56         }
    57     }
    58     return false;
    59 }
    60 
    61 int main() {
    62     //FIN;
    63     scanf("%d", &t);
    64     int icase = 0;
    65     while(t--) {
    66         scanf("%d", &n);
    67         memset(vis, 0, sizeof(vis));
    68         for(int i = 1; i <= n; i++) {
    69             scanf("%s", s[i] + 1);
    70             len[i] = strlen(s[i] + 1);
    71             get_next(i);
    72         }
    73         int flag = 1;
    74         for(int i = n; i >= 2; i--) {
    75             if(kmp(i, i-1)) {
    76                 vis[i-1] = 1;
    77             }
    78         }
    79         for(int i = n; i >= 2; i--) {
    80             for(int j = i - 1; j >= 1; j--) {
    81                 if(!vis[j] && !kmp(i, j)) {
    82                     flag = i;
    83                     break;
    84                 }
    85             }
    86             if(flag != 1) break;
    87         }
    88         printf("Case #%d: ", ++icase);
    89         if(flag != 1) printf("%d
    ", flag);
    90         else printf("-1
    ");
    91     }
    92     return 0;
    93 }
  • 相关阅读:
    redis相关
    Ubuntu安装之python开发
    Shell编程实战
    saltstack高效运维
    docker网络
    docker入门
    python学习博客地址集合。。。
    vue+uwsgi+nginx部署路飞学城
    部署你的CRM程序
    Java Netty教程(目录)
  • 原文地址:https://www.cnblogs.com/Dillonh/p/9424527.html
Copyright © 2020-2023  润新知