3374 String Problem

String Problem

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2521    Accepted Submission(s): 1063



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
and lexicographically first of them is GSKYLON, lexicographically last is YLONGSK, both of them appear only once.
  Your task is easy, calculate the lexicographically fisrt string’s Rank (if there are multiple answers, choose the smallest one), its times, lexicographically last string’s Rank (if there are multiple answers, choose the smallest one), and its times also.
 

Input
  Each line contains one line the string S with length N (N <= 1000000) formed by lower case letters.
 

Output
Output four integers separated by one space, lexicographically fisrt string’s Rank (if there are multiple answers, choose the smallest one), the string’s times in the N generated strings, lexicographically last string’s Rank (if there are multiple answers, choose the smallest one), and its times also.
 

Sample Input
  
  
abcder aaaaaa ababab
 

Sample Output
  
  
1 1 6 1 1 6 1 6 1 3 2 3

题意大意:给你一个字符串,求它的同构字符串中字典序最小的和字典序最大的起始位置以及出现的次数。同构字符串指的是一个字符串通过循环移位得到的字符串,题目中也有解释,应该是可以看懂的。
思路:
(一)求出它的同构循环串,用map存储出现的次数,然后排序,就可以求出答案了。代码如下,提交超内存。

<span style="font-size:18px;">#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#define LL long long
using namespace std;
const int maxn = 1000000+5;
struct node{
    string s;
    int r;
}ss[maxn];
bool cmp(node x,node y)
{
    if(x.s!=y.s) return x.s<y.s;
    return x.r<y.r;
}
int main()
{
    cin.sync_with_stdio(false);
    string a,b;
    int la,c;
    while(cin>>a){
        map<string,int>m;
        la=a.size();
        c=0;
        m[a]++;
        ss[c].s=a;
        ss[c++].r=1;
        for(int i=1;i<la;i++){
            b=a.substr(i)+a.substr(0,i);
            //cout<<"b="<<b<<endl;
            ss[c].s=b;
            ss[c++].r=i+1;
            m[b]++;
        }
        sort(ss,ss+c,cmp);
        //for(int i=0;i<c;i++) cout<<ss[i].s<<' '<<ss[i].r<<endl;
        cout<<ss[0].r<<' '<<m[ss[0].s]<<' ';
        int t=la-1;
        while(ss[t].s==ss[t-1].s){
            t--;
            if(t==0) break;
        }
        cout<<ss[t].r<<' '<<m[ss[t].s]<<endl;
    }
    return 0;
}</span>

(二)用最小表示法求字典序最小的字符串,最大表示法求字典序最大的字符串,next数组求出现的次数。
最小表示法:已知了起始坐标就可以唯一确定同构循环串,分别用i和j表示两个不同的循环串的起始位置,k表示比较的长度,解释一下下面的语句吧
if(s[(i+k)%ls]>s[(j+k)%ls]) i=i+k+1; //因为s[i]~s[(i+k-1)%ls]==s[j]~s[(j+k-1)%ls],所有当s[(i+k)%ls]>s[(j+k)%ls]时可以得出i~(i+k-1)%ls中以任意坐标开始的都要比j~(j+k-1)%ls的要大,所有i可以直接等于i+k+1
next数组可以求出一个字符串的循环节,比如字符串s,ls=s.size(),那么s的循环节的长度len=ls-next[ls],所有出现的次数为ls/len。 这个AC
<span style="font-size:18px;">#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#define LL long long
using namespace std;
const int maxn = 1000000+5;
int Next[maxn];
void getNext(string s)
{
    int ls=s.size();
    Next[0]=-1;
    Next[1]=0;
    for(int i=2;i<=ls;i++){
        if(s[i-1]==s[Next[i-1]]) Next[i]=Next[i-1]+1;
        else{
            int t=Next[i-1];
            while(s[i-1]!=s[t]){
                t=Next[t];
                if(t==-1) break;
            }
            Next[i]=t+1;
        }
    }
}
int getMin(string s)
{
    int ls=s.size();
    int i=0,j=1,k=0;
    while(i<ls && j<ls && k<ls){   //k<ls 一定要写,因为当s=aaaaa时不写会死循环
        if(s[(i+k)%ls]==s[(j+k)%ls]) k++;
        else{
            if(s[(i+k)%ls]>s[(j+k)%ls]) i=i+k+1;         
                     else j=j+k+1;
            if(i==j) j++;
            k=0;
        }
    }
    return min(i,j);
}
int getMax(string s)
{
    int ls=s.size();
    int i=0,j=1,k=0;
    while(i<ls && j<ls && k<ls){
        if(s[(i+k)%ls]==s[(j+k)%ls]) k++;
        else{
            if(s[(i+k)%ls]>s[(j+k)%ls]) j=j+k+1;
            else i=i+k+1;
            if(i==j) j++;
            k=0;
        }
    }
    return min(i,j);
}
int main()
{
    cin.sync_with_stdio(false); //记得用c++要加这一句,因为不加会超时
    string s;
    int ls,len,smin,smax;
    while(cin>>s){
        getNext(s);
        ls=s.size();
        len=ls-Next[ls];
        smin=getMin(s)+1;
        smax=getMax(s)+1;
        cout<<smin<<' '<<ls/len<<' '<<smax<<' '<<ls/len<<endl;
    }
    return 0;
}</span>

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值