题意:摘自NOCOW翻译(http://www.nocow.cn/index.php/Translate:USACO/hidden)
描述
有时候程序员有很奇怪的方法来隐藏他们的口令。Billy"Hacker"Geits会选择一个字符串S(由L个小写字母组成,5<=L<=100,000),然后他把S顺时针绕成一个圈,每次取一个做开头字母并顺时针依次取字母而组成一个字符串。这样将得到一些字符串,他把它们排序后取出第一个字符串。把这个字符串的第一个字母在原字符串中的位置做为口令。
第一个字母所在的位置是0
如字符串alabala,按操作得到7个字符串,排序后得:
aalabal abalaal alaalab alabala balaala laalaba labalaa
第一个字符串为aalabal,这个a在原字符串位置为6,则6为口令。 当字符串相同时,输出编号最小的(即对于aaaa输出0)
[编辑]格式
PROGRAM NAME: hidden
INPUT FORMAT:
(file hidden.in)
INPUT FORMAT 第1行:一个数:L
第2..?行:字符串:S(每行72个字符,最后一行可能不够)
OUTPUT FORMAT:
(file hidden.out) 一行,为得到的口令
[编辑]SAMPLE INPUT
7 alabala
[编辑]SAMPLE OUTPUT
6
解题思路:
代码:
/*
ID: zc.rene1
LANG: C
PROG: hidden
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_L 200000
int L;
char s[MAX_L + 1];
void GetInput(FILE *fin)
{
fscanf(fin, "%d\n", &L);
memset(s, 0, (MAX_L + 1) * sizeof(char));
while (fscanf(fin, "%s\n", s + strlen(s)) == 1)
{
;
}
}
int GetMin(void)
{
int i = 0, j = 1, k = 0;
memcpy(s + L, s, L * sizeof(char));
while (j < L)
{
k = 0;
while (s[i + k] == s[j + k] && k < L)
{
k++;
}
if (k == L)
{
break;
}
if (s[i + k] > s[j + k])
{
i = j;
j = i + 1;
}
else
{
j += k + 1;
}
}
return i;
}
int main(void)
{
FILE *fin, *fout;
int i;
fin = fopen("hidden.in", "r");
fout = fopen("hidden.out", "w");
GetInput(fin);
fprintf(fout, "%d\n", GetMin());
return 0;
}