• 字符串 最小表示法


    定义:

    表示:
    若对于一个字符串 (S) ,和另一个字符串 (S^prime)
    若存在一个 (i) 使得 (S^prime[i...N]S^prime[1...i-1])(S) 相等,那么就说 (S^prime)(S) 的一个表示(也称 (S^prime)(S) 循环同构)。
    (S) 的最小表示就是满足上述条件的字典序最小(S^prime)


    算法复杂度

    我们还是先来看看暴力的复杂度:
    (O(n^2))
    枚举最小表示的开头,暴力判断是否循环同构。
    这种做法的时间主要消耗在比较上,如果是随机数据,则表现良好,但是如果是这种:

    [aaaa...aaa ]

    每次比较次数将达到 (O(n)) 级别,整个算法就成了 (O(n^2))
    而我们接下来的算法复杂度是妥妥的 (O(n))


    合理解法

    我们考虑两个字符串 (A,B),它们在 (S) 中的起始位置分别为 (i,j) ,且它们的前 (k) 位都相等。
    如果 (A[i+k]>B[j+k]) 那么对于任何一个字符串 (T) ,它的开头位于 (i)(i+k) 之间,那么它肯定不会成为最优解(想一想为什么)。
    所以我们就可以直接将 (i) 跳至 (i+k+1)
    复杂度证明:不会。。。


    模板题

    Luogu
    代码:

    /*--------------------------------
    --Author: The Ace Bee-------------
    --Blog: www.cnblogs.com/zsbzsb----
    --This code is made by The Ace Bee
    --------------------------------*/
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <cctype>
    #include <cmath>
    #include <ctime>
    #include <string>
    #define rg register
    #define clr(x, y) memset(x, y, sizeof x)
    using namespace std;
    template < typename T > inline void read(T& s) {
    	s = 0; int f = 0; char c = getchar();
    	while (!isdigit(c)) f |= (c == '-'), c = getchar();
    	while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar();
    	s = f ? -s : s;
    }
    
    const int _ = 30010;
    
    int n, L; char s[_], t[_];
    
    inline void solve() {
    	scanf("%s", s), L = strlen(s);
    	int k = 0, i = 0, j = 1;
    	while (k < L && i < L && j < L) {
    		int tmp = s[(i + k) % L] - s[(j + k) % L];
    		if (tmp == 0) ++k;
    		else {
    			if (tmp < 0) j += k + 1;
    			if (tmp > 0) i += k + 1;
    			if (i == j) ++i; k = 0;
    		}
    	}
    	printf("%d
    ", min(i, j) + 1);
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
    	freopen("in.in", "r", stdin);
    #endif
    	read(n);
    	for (rg int i = 1; i <= n; ++i) solve();
    	return 0;
    }
    
  • 相关阅读:
    scrapy 模块功能流程--转
    CP三次握手和四次分手--转
    获取免费IP--代码--转
    爬虫介绍+Jupyter Notebook--转
    In Ubuntu, How to install Chinese Pinyin with Fcitx?
    对json文件进行简单读写操作
    ubuntu 中wget (下载)命令用法
    如何更改Ubuntu 16.04 默认Python版本方法
    如何将本地文件上传通过命令行命令上传到远程服务器上
    Ubuntu上,如何成功的安装pygrib
  • 原文地址:https://www.cnblogs.com/zsbzsb/p/11627122.html
Copyright © 2020-2023  润新知