最小表示法
Posted zgqblogs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最小表示法相关的知识,希望对你有一定的参考价值。
https://vjudge.net/contest/282991#problem/E
别人的博客:https://wizmann.tk/minimal-round-string.html
我自己想了一个证明方式,已经满足自己了,只不过自己证出来的东西,放在博客上怕误人子弟,要是你非要看的话。。。
先写完那个CF的题,再看完我的代码才行
#include<iostream> #include<algorithm> #include<vector> #include<stack> #include<queue> #include<map> #include<set> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #define fuck(x) cout<<#x<<" = "<<x<<endl; #define ls (t<<1) #define rs ((t<<1)+1) using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn = 2000086; const int inf = 2.1e9; const ll Inf = 999999999999999999; const int mod = 1000000007; const double eps = 1e-6; const double pi = acos(-1); int n; char s[maxn]; bool judge() { for(int i=2;i<=n;i++){ if(s[i]<s[1]){return false;} else if(s[i]==s[1]){ int k=0; for(int j=1;j+i<=2*n;j++,k++){ if(s[j]>s[i+j-1]){return false;} else if(s[j]<s[i+j-1]){break;} } i+=k; } } return true; } int main() { // ios::sync_with_stdio(false); // freopen("in.txt","r",stdin); scanf("%d",&n); scanf("%s",s+1); for(int i=1;i<=n;i++){ s[i+n]=s[i]; } if(judge()){printf("Yes ");} else printf("No "); return 0; }
有 S1_S2_C1 S1_S2_C2 ;S1,S2都是相同的开头,S1在字符串首。
j作为一个指针向后移动,如果已经移动到了第二个S1处,并且比较C1和C2的时候,发现C1<C2了,这个时候就不用把j挪到S2那里去了,因为S2早就被测过,而且是面对比C2还小的C1,他都通过了测试,那么面对C2,当然更没有问题。
以上是关于最小表示法的主要内容,如果未能解决你的问题,请参考以下文章
2021-12-24:划分字母区间。 字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。 力扣763。某大厂面试