[coj 1353 Guessing the Number]kmp,字符串最小表示法
题意:给一个字符串,求它的最小子串,使得原串是通过它重复得到的字符串的一个子串。
思路:先求最小长度,最小循环长度可以利用kmp的next数组快速得到,求出长度后然后利用字符串最小表示法求循环节的最小表示即可。
- #pragma comment(linker, "/STACK:10240000")
- #include <map>
- #include <set>
- #include <cmath>
- #include <ctime>
- #include <deque>
- #include <queue>
- #include <stack>
- #include <vector>
- #include <cstdio>
- #include <string>
- #include <cstdlib>
- #include <cstring>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- #define X first
- #define Y second
- #define pb push_back
- #define mp make_pair
- #define all(a) (a).begin(), (a).end()
- #define fillchar(a, x) memset(a, x, sizeof(a))
- #define fillarray(a, b) memcpy(a, b, sizeof(a))
- typedef long long ll;
- typedef pair<int, int> pii;
- typedef unsigned long long ull;
- #ifndef ONLINE_JUDGE
- namespace Debug {
- void RI(vector<int>&a,int n){a.resize(n);for(int i=;i<n;i++)scanf("%d",&a[i]);}
- void RI(){}void RI(int&X){scanf("%d",&X);}template<typename...R>
- void RI(int&f,R&...r){RI(f);RI(r...);}void RI(int*p,int*q){int d=p<q?:-;
- while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T>
- void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
- void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>
- void print(T*p, T*q){int d=p<q?:-;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
- }
- #endif // ONLINE_JUDGE
- template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
- template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}
- const double PI = acos(-1.0);
- const int INF = 0x3f3f3f3f;
- const double EPS = 1e-8;
- /* -------------------------------------------------------------------------------- */
- const int maxn = 2e5 + ;
- struct KMP {
- int next[maxn];
- void GetNext(char s[]) {
- fillchar(next, );
- next[] = next[] = ;
- for(int i = ; s[i]; i++) {
- int j = next[i];
- while(j && s[i] != s[j]) j = next[j];
- next[i + ] = s[j] == s[i]? j + : ;
- }
- }
- };
- KMP kmp;
- char s[maxn];
- void work(char s[], int n) {
- int i = , j = ; /** 用i存最小表示的最小可能位置, 同时令j>i,因为0~i-1都不是最小表示*/
- while (i < n && j < n) {
- while (s[i] == '0') i ++;
- umax(j, i + );
- while (s[j] == '0') j ++;
- //Debug::print(i, j, n);
- if (j >= n) break;
- int k = ;
- while (s[i + k] == s[j + k] && k <= n) k ++;
- if (s[i + k] > s[j + k]) if (s[j + k] != '0') i += k + ; else i += k;
- else if (s[i + k] != '0') j += k + ; else j += k;
- //Debug::print(i, j, n);
- }
- int x = i < n? i : j; /** 最后一次可能跳跃导致i大于等于n,那么此时的j一定是最小表示 */
- for (int i = x; i < x + n; i ++) {
- putchar(s[i]);
- }
- putchar('\n');
- }
- int main() {
- #ifndef ONLINE_JUDGE
- freopen("in.txt", "r", stdin);
- // //freopen("out.txt", "w", stdout);
- #endif // ONLINE_JUDGE
- int T;
- cin >> T;
- while (T --) {
- scanf("%s", s);
- int n = strlen(s);
- bool ok = false;
- for (int i = ; s[i]; i ++) {
- if (s[i] != '0') {
- ok = true;
- break;
- }
- }
- if (!ok) {
- s[n ++] = '1';
- s[n] = ;
- }
- kmp.GetNext(s);
- int len = n - kmp.next[n];
- for (int i = len; i < * len; i ++) s[i] = s[i - len];
- s[ * len] = ;
- work(s, len);
- }
- return ;
- }
[coj 1353 Guessing the Number]kmp,字符串最小表示法的更多相关文章
- O - String Problem KMP 字符串最小表示法
Give you a string with length N, you can generate N strings by left shifts. For example let consider ...
- bzoj5130 字符串的周期(kmp,最小表示法)
bzoj5130 字符串的周期(kmp,最小表示法) bzoj 题解时间 m很大,n很小. 周期很容易求,就是kmp之后n-fail[n]. 之后对于枚举所有的字符串用最小表示法,暴力搜索. 能过就完 ...
- 牛客练习赛36 A Rabbit的字符串(字符串最小表示法)
链接:https://ac.nowcoder.com/acm/contest/328/A来源:牛客网 题目描述 Rabbit得到了一个字符串,她的好朋友xxx可以给这个字符串施加一次魔法. 魔法可以选 ...
- bzoj2176 Strange string(字符串最小表示法)
Time Limit: 10 Sec Memory Limit: 259 MB 给定一个字符串S = {S1, S2, S3 … Sn}, 如果在串SS中, 子串T(|T| = n)为所有长度为n的 ...
- hdu3374 String Problem KMP+最大最小表示法
Give you a string with length N, you can generate N strings by left shifts. For example let consider ...
- BZOJ1398: Vijos1382寻找主人 Necklace 字符串最小表示法
Description 给定两个项链的表示,判断他们是否可能是一条项链. Input 输入文件只有两行,每行一个由0至9组成的字符串,描述一个项链的表示(保证项链的长度是相等的). Output 如果 ...
- Manacher模板,kmp,扩展kmp,最小表示法模板
*N]; //储存临时串 *N];//中间记录 int Manacher(char tmp[]) { int len=strlen(tmp); ; ;i<len;i++) { s[cnt++]= ...
- hdu 3374 String Problem (kmp+最大最小表示法)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题目大意:输出最大和最小的是从哪一位开始的,同时输出最小循环节的个数. 这里简单介绍对字符串最小 ...
- POJ 1509 Glass Beads【字符串最小表示法】
题目链接: http://poj.org/problem?id=1509 题意: 求循环字符串的最小表示. 分析: 浅析"最小表示法"思想在字符串循环同构问题中的应用 判断两字符串 ...
随机推荐
- H - Hamiltonian Hypercube Gym - 101170H
规律题 首先我们要知道他的顺序是怎么来的,首先当n等于1时,是0,1 当n=2时,先按照与按顺序在他们前面分别加0,即00,01,在逆序加1,即11,10 构成的顺序为00,01,11,10:往后同理 ...
- Xshell 设置右键粘贴即是复制
打开工具->选项->键盘和鼠标面板 1.鼠标部分的右击设置"粘贴剪切板的内容". 2.选择部分,在"自动将所选文本复制到剪切板"前打勾
- vue2.x学习笔记(十六)
接着前面的内容:https://www.cnblogs.com/yanggb/p/12616543.html. 组件中的插槽 在2.6.0的版本中,vue为具名插槽和作用域插槽引入了一个新的统一的语法 ...
- SQL Server 之T-SQL基本语句 (3)
继续来用例子总结sql基本语句用法. 在这里在建一个表:课 课程名 上课时间 数学 周一 数学 周二 数学 周三 语文 周一 语文 周二 英语 周一 数据分组:GROUP BY select 课程 ...
- Java中集合概念
集合的由来: 我们学习的是面向对象语言,而面向对象语言对事物的描述是通过对象体现的,为了方便对多个对象进行操作,我们就必须把这多个对象进行储存,而想要储存多个对象,就不能是一个基本的变量,而应该是一个 ...
- Jquery中 $.Ajax() 参数详解
1.url:要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type:要求为String类型的参数,请求方式(post或get)默认为get.注意其他http请求方法,例如pu ...
- 架构师修炼之微服务部署 - 深入理解Docker镜像
镜像简介 它是一个创建Docker 容器的只读模板,通过DockerFile可以自定义镜像. 它也是一个特殊的文件系统,除了提供容器运行时所需的程序.库.资源.配置等文件外,还包含了一些为运行时准备的 ...
- Java IO 流 -- 设计模式:装饰设计模式
在java IO 流中我们经常看到这样的写法: ObjectOutputStream oos = new ObjectOutputStream( new BufferedOutputStream(ne ...
- php phpStudy session存放位置
如果你仅仅是想知道session保存的文件在哪里,你可以在你的PHP文件当中运行函数:session_save_path之后查看运行结果即可知道session文件的存放目录. 或者: 在php-ini ...
- Inno Setup 大师 Tlama
https://stackoverflow.com/users/960757/tlama