洛谷P1709 [USACO5.5]隐藏口令Hidden Password

P1709 [USACO5.5]隐藏口令Hidden Password

题目描述

有时候程序员有很奇怪的方法来隐藏他们的口令。Binny会选择一个字符串S(由N个小写字母组成,5<=N<=5,000,000),然后他把S顺时针绕成一个圈,每次取一个做开头字母并顺时针依次取字母而组成一个字符串。这样将得到一些字符串,他把它们排序后取出第一个字符串。把这个字符串的第一个字母在原字符串中的位置-1做为口令。

如字符串alabala,按操作的到7个字符串,排序后得:

aalabal

abalaal

alaalab

alabala

balaala

laalaba

labalaa

第一个字符串为aalabal,这个a在原字符串位置为7,7-1=6,则6为口令。

输入输出格式

输入格式:

第一行:一个数:N

第二行开始:字符串:S(每72个字符一个换行符)

输出格式:

一行,为得到的口令

输入输出样例

输入样例#1: 复制
7
anabana
输出样例#1: 复制
6

说明

题目满足:

30%的数据n<=10000

70%的数据n<=100000

100%的数据n<=5000000

时限 1s

题目翻译来自NOCOW。

USACO Training Section 5.5

//20170523新增数据四组

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,ans;
string s,ss,snow;
int main(){
    freopen("Cola.txt","r",stdin);
    scanf("%d",&n);
    int tim=n/72;
    if(n/72*72!=n)tim++;
    for(int i=1;i<=tim;i++){
        cin>>ss;
        s+=ss;
    }
    s+=s;
    snow=s.substr(0,n);
    for(int i=1;i<n;i++){//枚举起点 
        for(int j=i,cnt=0;cnt<n;cnt++,j++){
            if(snow[cnt]==s[j])continue;
            if(snow[cnt]<s[j])break;
            if(snow[cnt]>s[j]){
                snow=s.substr(i,n);
                ans=i;
                break;
            }
        }
    }
    cout<<ans;
}
93分 暴力
#include <bits/stdc++.h>
using namespace std;
const int maxn=5000110;
int n;
char s[maxn*2];
int Mini(int l){    
    int i,j,k;  
    i=0;j=1;k=0;  
    while(i<l&&j<l){  
        k=0;  
        while(s[i+k]==s[j+k]&&k<l) k++;  
        if(k==l)return (i<j)?i:j;  
        if(s[i+k]>s[j+k])i=i+k+1;
        else j=j+k+1;
        if(i==j)j++;
    } 
    return (i<j)?i:j;
}     
int main(){
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>s[i];
        s[i+n]=s[i];
    }
    int l=Mini(n);
    cout<<l<<endl;
    return 0;
}
100分 贪心
原文地址:https://www.cnblogs.com/thmyl/p/7799198.html