您的位置:首页 > 其它

洛谷P1709 隐藏口令Hidden Password

2017-10-18 17:28 169 查看
题目描述

有时候程序员有很奇怪的方法来隐藏他们的口令。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

正解,用两个指针指向头和头的下一个。如果头相同,就利用一个k继续向后比较,如果在某一位失配,直接将答案更不优的指针移到失配的下一位。(因为如果一个个继续移位比较的话,以失配前的点为头的串肯定不如k更优),然后继续比较,直到边界位置。

复杂度应该是O(N)。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int maxn=10000005;
char shu[maxn];
int main()
{
int n;
bool flag=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)   cin>>shu[i];
for(int i=n+1;i<=2*n;i++)   shu[i]=shu[i-n];//现将数组复制一遍
int i=1,j=2,k=0;
while(i<=n&&j<=n)
{
k=0;
while(shu[i+k]==shu[j+k]&&k<n) k++;
if(k==n)
{
printf("%d",min(i,j)-1);
flag=1;
break;
}
if(shu[i+k]>shu[j+k])   i+=k+1;
else j+=k+1;
if(i==j) j++;
}
if(!flag) printf("%d\n",min(i,j)-1);
return 0;
}


错解:暴力匹配。洛谷上T一个点。先复制一下数组,然后开始逐位比较。比较到不同的,break掉

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int maxn=10000005;
char shu[maxn],bj[maxn];
int main()
{

int l,jl=0;
scanf("%d",&l);
for(int i=1;i<=l;i++)    cin>>shu[i];
for(int i=l+1;i<=2*l;i++)    shu[i]=shu[i-l];
for(int i=1;i<=l;i++) bj[i]=shu[i];
for(int i=1;i<l;i++)
{
bool flag=0;
for(int j=1;j<=l;j++)
{
if(shu[j+i]<bj[j])
{
flag=1;
break;
}
if(shu[j+i]>bj[j]) break;
}
if(flag==1)
{
jl=i;
for(int j=1;j<=l;j++)
bj[j]=shu[j+i];
}
}
printf("%d\n",jl);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: