hdu P3374 String Problem

今天又在lyk大佬的博客学会了——最小表示法(异常激动
发篇题解纪念一下
说在前面:给luogu提个建议最小表示法的题太少了,都被hdu抢去了!!!




我们先看一下题目

看完后可以用一个字概括——,两个字——懵逼

在这里我提供题目大意:

输出最大和最小的是从哪一位开始的,同时输出最小循环节的个数。

由于本人懒于写字符串最小表示法,那么我们就来借鉴一下lykkk优秀总结

看完之后,显然我们就明白了许多

因为题目中让我们同时求出最大和最小的起始位置

所以我们不仅要来一遍最小表示法,还要来一遍最大表示法

其实这两种算法唯一的区别就是:

最小表示法中当str[i+k]>str[j+k]时,i+k的字典序比j+k的字典序大,那么我们就要抛弃当前以i为头的字符串,往后走即i+=k+1

最大表示法就是当str[i+k]<str[j+k]时,我们才要更新起点

各来一遍后,题目就完成了一半

至于KMP在这里的作用就是,利用next数组来求循环节,则次数=长度/循环节长度

说到这里,显然三个子函数足以解决这个问题了

我们最后只需要在主函数里根据题意输入输出即可

无代码,不成方圆

#include<bits/stdc++.h>
using namespace std;
const int N = 1100000;
int n;
char s[N];
int nxt[N];
void Kmp(int l){//用来求最小循环节的个数
    int j=0,k=nxt[0]=-1;
    while(j<l){
        if(k==-1 || s[j]==s[k]) nxt[++j]=++k;
        else k=nxt[k];
    }
}
int Min(char s[],int l){
    int i=0,j=1,k=0;
    while(i<l && j<l && k<l){
        if(s[(i+k)%l]==s[(j+k)%l]) k++;
        else if(s[(i+k)%l]>s[(j+k)%l]) i+=k+1,k=0;
        else j+=k+1,k=0;
        if(i==j) i++;
    }
    return min(i,j);
}
int Max(char s[],int n){
    int i=0,j=1,k=0;
    while(i<n && j<n && k<n){
        if(s[(i+k)%n]==s[(j+k)%n]) k++;
        else if(s[(i+k)%n]<s[(j+k)%n]) i+=k+1,k=0;//唯一的区别
        else j+=k+1,k=0;
        if(i==j) i++;
    }
    return min(i,j);
}
int main(){//常规操作
    while(scanf("%s",s)!=EOF){
        int len=strlen(s);
        Kmp(len);
        int maxn=Max(s,len),minn=Min(s,len);
        printf("%d %d %d %d\n",minn+1,len/(len-nxt[len]),maxn+1,len/(len-nxt[len]));
    }
    return 0;
}

完结,撒花!

原文地址:https://www.cnblogs.com/xmex/p/10505906.html

时间: 2024-08-10 16:06:18

hdu P3374 String Problem的相关文章

hdu 3374 String Problem (kmp+最大最小表示法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3374 题目大意:输出最大和最小的是从哪一位开始的,同时输出最小循环节的个数. 这里简单介绍对字符串最小表示的方法: (1)  利用两个指针p1, p2.初始化时p1指向s[0], p2指向s[1]. (2)  k = 0开始,检验s[p1+k] 与 s[p2+k] 对应的字符是否相等,如果相等则k++,一直下去,直到找到第一个不同,(若k试了一个字符串的长度也没找到不同,则那个位置就是最小表示位置,

HDU 3374 String Problem (KMP+最大最小表示)

KMP,在有循环节的前提下: 循环节 t = len-next[len], 个数num = len/(len-next[len]); 个人理解,如果有循环节,循环节长度必定小于等于len/2, 换句话说next[len]>=len/2; 对于len%(len-next)!=0的这种情况不讨论,循环节不存在. 下面是假设循环节存在的情况 当次数等于2, 对于abcabc这种情况就不用说了,len = 6, next[len] = 3; 当次数大于2, 对于串a1 a2 a3 a4 a5 a6 a7

hdu 5772 String problem(最大权闭合图)

题目链接:hdu 5772 String problem 题意: 给你一个字符串,只含有数字. 你需要选择出一个子序列,使得这个子序列的权值最大. 这个子序列如果这个数字第一次出现就ans-=bx,否则就-=ax 然后如果第i个字符和第j个字符都在子序列里面,那么ans+=w[i][j] 问你最大ans是多少 官方题解: 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace

hdu 3374 String Problem

String Problem http://acm.hdu.edu.cn/showproblem.php?pid=3374 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3153    Accepted Submission(s): 1272 Problem Description Give you a string with leng

HDU 3374 String Problem (KMP+最大最小表示)

转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526       by---cxlove 题目:输出最大最小表示是从哪一位开始,而且输出数量 http://acm.hdu.edu.cn/showproblem.php?pid=3374 数量好求,肯定是字符串的循环节,循环节可以直接通过KMP的Next数组得到.这个和yobobobo曾经研究过半天.. 对于最大最小表示法,就是将字符串不断旋转,得到字典序最大或者最小的.

HDU 3374 String Problem(最大最小表示)

Description: Give you a string with length N, you can generate N strings by left shifts. For example let consider the string “SKYLONG”, we can generate seven strings: String Rank SKYLONG 1 KYLONGS 2 YLONGSK 3 LONGSKY 4 ONGSKYL 5 NGSKYLO 6 GSKYLON 7 a

HDU 5772 String problem

最大权闭合子图.建图巧妙. 最大权闭合子图: #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include

hdu String Problem(最小表示法入门题)

hdu 3374 String Problem 最小表示法 view code#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <string> using namespace std; const int N = 10010; int n; char s[105]; map<

hdu 5008(2014 ACM/ICPC Asia Regional Xi&#39;an Online ) Boring String Problem(后缀数组&amp;二分)

Boring String Problem Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 219    Accepted Submission(s): 45 Problem Description In this problem, you are given a string s and q queries. For each que